diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/slg/ClientSLgSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/slg/ClientSLgSessionDataReplicatedImpl.java new file mode 100644 index 000000000..d11876c4a --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/slg/ClientSLgSessionDataReplicatedImpl.java @@ -0,0 +1,64 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.client.slg; + +import org.restcomm.cache.FqnWrapper; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.impl.app.slg.IClientSLgSessionData; +import org.jdiameter.common.api.app.slg.SLgSessionState; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.common.slg.SLgSessionDataReplicatedImpl; +import org.mobicents.diameter.impl.ha.data.ReplicatedSessionDatasource; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ClientSLgSessionDataReplicatedImpl extends SLgSessionDataReplicatedImpl implements IClientSLgSessionData { + + /** + * @param nodeFqnWrapper + * @param mobicentsCluster + * @param container + */ + public ClientSLgSessionDataReplicatedImpl(FqnWrapper nodeFqnWrapper, MobicentsCluster mobicentsCluster, IContainer container) { + super(nodeFqnWrapper, mobicentsCluster, container); + + if (super.create()) { + setAppSessionIface(this, ClientSLgSession.class); + setSLgSessionState(SLgSessionState.IDLE); + } + } + + /** + * @param sessionId + * @param mobicentsCluster + * @param container + */ + public ClientSLgSessionDataReplicatedImpl(String sessionId, MobicentsCluster mobicentsCluster, IContainer container) { + this( + FqnWrapper.fromRelativeElementsWrapper(ReplicatedSessionDatasource.SESSIONS_FQN, sessionId), mobicentsCluster, container); + } + +} diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/slh/ClientSLhSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/slh/ClientSLhSessionDataReplicatedImpl.java new file mode 100644 index 000000000..016b09fa9 --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/client/slh/ClientSLhSessionDataReplicatedImpl.java @@ -0,0 +1,64 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.client.slh; + +import org.restcomm.cache.FqnWrapper; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.impl.app.slh.IClientSLhSessionData; +import org.jdiameter.common.api.app.slh.SLhSessionState; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.common.slh.SLhSessionDataReplicatedImpl; +import org.mobicents.diameter.impl.ha.data.ReplicatedSessionDatasource; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ClientSLhSessionDataReplicatedImpl extends SLhSessionDataReplicatedImpl implements IClientSLhSessionData { + + /** + * @param nodeFqnWrapper + * @param mobicentsCluster + * @param container + */ + public ClientSLhSessionDataReplicatedImpl(FqnWrapper nodeFqnWrapper, MobicentsCluster mobicentsCluster, IContainer container) { + super(nodeFqnWrapper, mobicentsCluster, container); + + if (super.create()) { + setAppSessionIface(this, ClientSLhSession.class); + setSLhSessionState(SLhSessionState.IDLE); + } + } + + /** + * @param sessionId + * @param mobicentsCluster + * @param container + */ + public ClientSLhSessionDataReplicatedImpl(String sessionId, MobicentsCluster mobicentsCluster, IContainer container) { + this( + FqnWrapper.fromRelativeElementsWrapper(ReplicatedSessionDatasource.SESSIONS_FQN, sessionId), mobicentsCluster, container); + } + +} \ No newline at end of file diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slg/SLgReplicatedSessionDataFactory.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slg/SLgReplicatedSessionDataFactory.java new file mode 100644 index 000000000..c54544bb6 --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slg/SLgReplicatedSessionDataFactory.java @@ -0,0 +1,72 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.common.slg; + +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.common.api.app.IAppSessionDataFactory; +import org.jdiameter.common.api.app.slg.ISLgSessionData; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.client.slg.ClientSLgSessionDataReplicatedImpl; +import org.mobicents.diameter.impl.ha.data.ReplicatedSessionDatasource; +import org.mobicents.diameter.impl.ha.server.slg.ServerSLgSessionDataReplicatedImpl; + +/** + * + * @author Fernando Mendioroz + * + */ +public class SLgReplicatedSessionDataFactory implements IAppSessionDataFactory { + + private ReplicatedSessionDatasource replicatedSessionDataSource; + private MobicentsCluster mobicentsCluster; + + /** + * @param replicatedSessionDataSource + */ + public SLgReplicatedSessionDataFactory(ISessionDatasource replicatedSessionDataSource) { // Is this ok? + super(); + this.replicatedSessionDataSource = (ReplicatedSessionDatasource) replicatedSessionDataSource; + this.mobicentsCluster = this.replicatedSessionDataSource.getMobicentsCluster(); + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) + */ + public ISLgSessionData getAppSessionData(Class clazz, String sessionId) { + if (clazz.equals(ClientSLgSession.class)) { + ClientSLgSessionDataReplicatedImpl data = new ClientSLgSessionDataReplicatedImpl(sessionId, this.mobicentsCluster, + this.replicatedSessionDataSource.getContainer()); + return data; + } else if (clazz.equals(ServerSLgSession.class)) { + ServerSLgSessionDataReplicatedImpl data = new ServerSLgSessionDataReplicatedImpl(sessionId, this.mobicentsCluster, + this.replicatedSessionDataSource.getContainer()); + return data; + } + throw new IllegalArgumentException(); + } + +} diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slg/SLgSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slg/SLgSessionDataReplicatedImpl.java new file mode 100644 index 000000000..cc69afa49 --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slg/SLgSessionDataReplicatedImpl.java @@ -0,0 +1,150 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.common.slg; + +import java.io.Serializable; +import java.nio.ByteBuffer; + +import org.restcomm.cache.FqnWrapper; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.Request; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.api.IMessage; +import org.jdiameter.client.api.parser.IMessageParser; +import org.jdiameter.client.api.parser.ParseException; +import org.jdiameter.common.api.app.slg.SLgSessionState; +import org.jdiameter.common.api.app.slg.ISLgSessionData; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.common.AppSessionDataReplicatedImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class SLgSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements ISLgSessionData { + + private static final Logger logger = LoggerFactory.getLogger(SLgSessionDataReplicatedImpl.class); + + private static final String STATE = "STATE"; + private static final String BUFFER = "BUFFER"; + private static final String TS_TIMERID = "TS_TIMERID"; + + private IMessageParser messageParser; + + /** + * @param nodeFqnWrapper + * @param mobicentsCluster + * @param container + */ + public SLgSessionDataReplicatedImpl(FqnWrapper nodeFqnWrapper, MobicentsCluster mobicentsCluster, IContainer container) { + super(nodeFqnWrapper, mobicentsCluster); + this.messageParser = container.getAssemblerFacility().getComponentInstance(IMessageParser.class); + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slg.ISLgSessionData#setSLgSessionState(org.jdiameter.common.api.app.slg.SLgSessionState) + */ + public void setSLgSessionState(SLgSessionState state) { + if (exists()) { + getNode().put(STATE, state); + } else { + throw new IllegalStateException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slg.ISLgSessionData#getSLgSessionState() + */ + public SLgSessionState getSLgSessionState() { + if (exists()) { + return (SLgSessionState) getNode().get(STATE); + } + else { + throw new IllegalStateException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slg.ISLgSessionData#getTsTimerId() + */ + public Serializable getTsTimerId() { + if (exists()) { + return (Serializable) getNode().get(TS_TIMERID); + } + else { + throw new IllegalStateException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slg.ISLgSessionData#setTsTimerId(java.io.Serializable) + */ + public void setTsTimerId(Serializable tid) { + if (exists()) { + getNode().put(TS_TIMERID, tid); + } + else { + throw new IllegalStateException(); + } + } + + public Request getBuffer() { + byte[] data = (byte[]) getNode().get(BUFFER); + if (data != null) { + try { + return (Request) this.messageParser.createMessage(ByteBuffer.wrap(data)); + } catch (AvpDataException e) { + logger.error("Unable to recreate message from buffer."); + return null; + } + } else { + return null; + } + } + + public void setBuffer(Request buffer) { + if (buffer != null) { + try { + byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); + getNode().put(BUFFER, data); + } + catch (ParseException e) { + logger.error("Unable to encode message to buffer."); + } + } + else { + getNode().remove(BUFFER); + } + } + +} \ No newline at end of file diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slh/SLhReplicatedSessionDataFactory.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slh/SLhReplicatedSessionDataFactory.java new file mode 100644 index 000000000..2f337ce45 --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slh/SLhReplicatedSessionDataFactory.java @@ -0,0 +1,72 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.common.slh; + +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.common.api.app.IAppSessionDataFactory; +import org.jdiameter.common.api.app.slh.ISLhSessionData; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.client.slh.ClientSLhSessionDataReplicatedImpl; +import org.mobicents.diameter.impl.ha.data.ReplicatedSessionDatasource; +import org.mobicents.diameter.impl.ha.server.slh.ServerSLhSessionDataReplicatedImpl; + +/** + * + * @author Fernando Mendioroz + * + */ +public class SLhReplicatedSessionDataFactory implements IAppSessionDataFactory { + + private ReplicatedSessionDatasource replicatedSessionDataSource; + private MobicentsCluster mobicentsCluster; + + /** + * @param replicatedSessionDataSource + */ + public SLhReplicatedSessionDataFactory(ISessionDatasource replicatedSessionDataSource) { // Is this ok? + // super(); + this.replicatedSessionDataSource = (ReplicatedSessionDatasource) replicatedSessionDataSource; + this.mobicentsCluster = this.replicatedSessionDataSource.getMobicentsCluster(); + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.IAppSessionDataFactory#getAppSessionData(java.lang.Class, java.lang.String) + */ + public ISLhSessionData getAppSessionData(Class clazz, String sessionId) { + if (clazz.equals(ClientSLhSession.class)) { + ClientSLhSessionDataReplicatedImpl data = new ClientSLhSessionDataReplicatedImpl(sessionId, this.mobicentsCluster, + this.replicatedSessionDataSource.getContainer()); + return data; + } else if (clazz.equals(ServerSLhSession.class)) { + ServerSLhSessionDataReplicatedImpl data = new ServerSLhSessionDataReplicatedImpl(sessionId, this.mobicentsCluster, + this.replicatedSessionDataSource.getContainer()); + return data; + } + throw new IllegalArgumentException(); + } + +} \ No newline at end of file diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slh/SLhSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slh/SLhSessionDataReplicatedImpl.java new file mode 100644 index 000000000..a8058ab0a --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/common/slh/SLhSessionDataReplicatedImpl.java @@ -0,0 +1,146 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.common.slh; + +import java.io.Serializable; +import java.nio.ByteBuffer; + +import org.restcomm.cache.FqnWrapper; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.Request; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.client.api.IMessage; +import org.jdiameter.client.api.parser.IMessageParser; +import org.jdiameter.client.api.parser.ParseException; +import org.jdiameter.common.api.app.slh.SLhSessionState; +import org.jdiameter.common.api.app.slh.ISLhSessionData; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.common.AppSessionDataReplicatedImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class SLhSessionDataReplicatedImpl extends AppSessionDataReplicatedImpl implements ISLhSessionData { + + private static final Logger logger = LoggerFactory.getLogger(SLhSessionDataReplicatedImpl.class); + + private static final String STATE = "STATE"; + private static final String BUFFER = "BUFFER"; + private static final String TS_TIMERID = "TS_TIMERID"; + + private IMessageParser messageParser; + + /** + * @param nodeFqnWrapper + * @param mobicentsCluster + * @param container + */ + public SLhSessionDataReplicatedImpl(FqnWrapper nodeFqnWrapper, MobicentsCluster mobicentsCluster, IContainer container) { + super(nodeFqnWrapper, mobicentsCluster); + this.messageParser = container.getAssemblerFacility().getComponentInstance(IMessageParser.class); + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slh.ISLhSessionData#setSLhSessionState(org.jdiameter.common.api.app.slh.SLhSessionState) + */ + public void setSLhSessionState(SLhSessionState state) { + if (exists()) { + getNode().put(STATE, state); + } else { + throw new IllegalStateException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slh.ISLhSessionData#getSLhSessionState() + */ + public SLhSessionState getSLhSessionState() { + if (exists()) { + return (SLhSessionState) getNode().get(STATE); + } else { + throw new IllegalStateException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slh.ISLhSessionData#getTsTimerId() + */ + public Serializable getTsTimerId() { + if (exists()) { + return (Serializable) getNode().get(TS_TIMERID); + } else { + throw new IllegalStateException(); + } + } + + /* + * (non-Javadoc) + * + * @see org.jdiameter.common.api.app.slh.ISLhSessionData#setTsTimerId(java.io.Serializable) + */ + public void setTsTimerId(Serializable tid) { + if (exists()) { + getNode().put(TS_TIMERID, tid); + } else { + throw new IllegalStateException(); + } + } + + public Request getBuffer() { + byte[] data = (byte[]) getNode().get(BUFFER); + if (data != null) { + try { + return (Request) this.messageParser.createMessage(ByteBuffer.wrap(data)); + } catch (AvpDataException e) { + logger.error("Unable to recreate message from buffer."); + return null; + } + } else { + return null; + } + } + + public void setBuffer(Request buffer) { + if (buffer != null) { + try { + byte[] data = this.messageParser.encodeMessage((IMessage) buffer).array(); + getNode().put(BUFFER, data); + } + catch (ParseException e) { + logger.error("Unable to encode message to buffer."); + } + } else { + getNode().remove(BUFFER); + } + } + +} \ No newline at end of file diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/data/ReplicatedSessionDatasource.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/data/ReplicatedSessionDatasource.java index 1ca5eb44a..d1158d540 100644 --- a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/data/ReplicatedSessionDatasource.java +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/data/ReplicatedSessionDatasource.java @@ -67,6 +67,8 @@ import org.jdiameter.common.api.app.sh.IShSessionData; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.data.LocalDataSource; +import org.jdiameter.common.api.app.slh.ISLhSessionData; +import org.jdiameter.common.api.app.slg.ISLgSessionData; import org.restcomm.cache.FqnWrapper; import org.restcomm.cache.MobicentsCache; import org.restcomm.cluster.DataRemovalListener; @@ -84,6 +86,8 @@ import org.mobicents.diameter.impl.ha.common.rx.RxReplicatedSessionDataFactory; import org.mobicents.diameter.impl.ha.common.s13.S13ReplicatedSessionDataFactory; import org.mobicents.diameter.impl.ha.common.sh.ShReplicatedSessionDataFactory; +import org.mobicents.diameter.impl.ha.common.slh.SLhReplicatedSessionDataFactory; +import org.mobicents.diameter.impl.ha.common.slg.SLgReplicatedSessionDataFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -137,7 +141,7 @@ public ReplicatedSessionDatasource(IContainer container, ISessionDatasource loca this.mobicentsCluster.startCluster(); this.container = container; - // this is coded, its tied to specific impl of SessionDatasource + // this is coded, it is tied to specific impl of SessionDatasource appSessionDataFactories.put(IAuthSessionData.class, new AuthReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IAccSessionData.class, new AccReplicatedSessionDataFactory(this)); appSessionDataFactories.put(ICCASessionData.class, new CCAReplicatedSessionDataFactory(this)); @@ -148,6 +152,8 @@ public ReplicatedSessionDatasource(IContainer container, ISessionDatasource loca appSessionDataFactories.put(IGxSessionData.class, new GxReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IRxSessionData.class, new RxReplicatedSessionDataFactory(this)); appSessionDataFactories.put(IS13SessionData.class, new S13ReplicatedSessionDataFactory(this)); + appSessionDataFactories.put(ISLhSessionData.class, new SLhReplicatedSessionDataFactory(this)); + appSessionDataFactories.put(ISLgSessionData.class, new SLgReplicatedSessionDataFactory(this)); } diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/server/slg/ServerSLgSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/server/slg/ServerSLgSessionDataReplicatedImpl.java new file mode 100644 index 000000000..62f1380c9 --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/server/slg/ServerSLgSessionDataReplicatedImpl.java @@ -0,0 +1,64 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.server.slg; + +import org.restcomm.cache.FqnWrapper; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.common.api.app.slg.SLgSessionState; +import org.jdiameter.server.impl.app.slg.IServerSLgSessionData; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.common.slg.SLgSessionDataReplicatedImpl; +import org.mobicents.diameter.impl.ha.data.ReplicatedSessionDatasource; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ServerSLgSessionDataReplicatedImpl extends SLgSessionDataReplicatedImpl implements IServerSLgSessionData { + + /** + * @param nodeFqnWrapper + * @param mobicentsCluster + * @param container + */ + public ServerSLgSessionDataReplicatedImpl(FqnWrapper nodeFqnWrapper, MobicentsCluster mobicentsCluster, IContainer container) { + super(nodeFqnWrapper, mobicentsCluster, container); + + if (super.create()) { + setAppSessionIface(this, ServerSLgSession.class); + setSLgSessionState(SLgSessionState.IDLE); + } + } + + /** + * @param sessionId + * @param mobicentsCluster + * @param container + */ + public ServerSLgSessionDataReplicatedImpl(String sessionId, MobicentsCluster mobicentsCluster, IContainer container) { + this( + FqnWrapper.fromRelativeElementsWrapper(ReplicatedSessionDatasource.SESSIONS_FQN, sessionId), mobicentsCluster, container); + } + +} \ No newline at end of file diff --git a/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/server/slh/ServerSLhSessionDataReplicatedImpl.java b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/server/slh/ServerSLhSessionDataReplicatedImpl.java new file mode 100644 index 000000000..4af47f1bf --- /dev/null +++ b/core/jdiameter-ha/impl/src/main/java/org/mobicents/diameter/impl/ha/server/slh/ServerSLhSessionDataReplicatedImpl.java @@ -0,0 +1,64 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.diameter.impl.ha.server.slh; + +import org.restcomm.cache.FqnWrapper; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.client.api.IContainer; +import org.jdiameter.common.api.app.slh.SLhSessionState; +import org.jdiameter.server.impl.app.slh.IServerSLhSessionData; +import org.restcomm.cluster.MobicentsCluster; +import org.mobicents.diameter.impl.ha.common.slh.SLhSessionDataReplicatedImpl; +import org.mobicents.diameter.impl.ha.data.ReplicatedSessionDatasource; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ServerSLhSessionDataReplicatedImpl extends SLhSessionDataReplicatedImpl implements IServerSLhSessionData { + + /** + * @param nodeFqnWrapper + * @param mobicentsCluster + * @param container + */ + public ServerSLhSessionDataReplicatedImpl(FqnWrapper nodeFqnWrapper, MobicentsCluster mobicentsCluster, IContainer container) { + super(nodeFqnWrapper, mobicentsCluster, container); + + if (super.create()) { + setAppSessionIface(this, ServerSLhSession.class); + setSLhSessionState(SLhSessionState.IDLE); + } + } + + /** + * @param sessionId + * @param mobicentsCluster + * @param container + */ + public ServerSLhSessionDataReplicatedImpl(String sessionId, MobicentsCluster mobicentsCluster, IContainer container) { + this( + FqnWrapper.fromRelativeElementsWrapper(ReplicatedSessionDatasource.SESSIONS_FQN, sessionId), mobicentsCluster, container); + } + +} \ No newline at end of file diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/Avp.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/Avp.java index c020f35ae..7afe1767e 100644 --- a/core/jdiameter/api/src/main/java/org/jdiameter/api/Avp.java +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/Avp.java @@ -2302,6 +2302,427 @@ public interface Avp extends Wrapper, Serializable { */ int TGPP2_MEID = 1471; + /********************************************************/ + /*** SLh interface (GMLC - HSS) AVPs (3GPP TS 29.173) ***/ + /********************************************************/ + + /** + * SLh (3GPP TS 29.173) LMSI AVP code + */ + int LMSI = 2400; + + /** + * SLh (3GPP TS 29.173) Serving-Node AVP code + */ + int SERVING_NODE = 2401; + + /** + * SLh (3GPP TS 29.173) MME-Name AVP code + */ + int MME_NAME = 2402; + + /** + * SLh (3GPP TS 29.173) MCS-Number AVP code + */ + int MSC_NUMBER = 2403; + + /** + * SLh (3GPP TS 29.173) LCS-Capabilities-Sets AVP code + */ + int LCS_CAPABILITIES_SETS = 2404; + + /** + * SLh (3GPP TS 29.173) GMLC-Address AVP code + */ + int GMLC_ADDRESS = 2405; + + /** + * SLh (3GPP TS 29.173) Additional-Serving-Node AVP code + */ + int ADDITIONAL_SERVING_NODE = 2406; + + /** + * SLh (3GPP TS 29.173) PPR-Address AVP code + */ + int PPR_ADDRESS = 2407; + + /** + * SLh (3GPP TS 29.173) MME-Realm AVP code + */ + int MME_REALM = 2408; + + /** + * SLh (3GPP TS 29.173) SGSN-Name AVP code + */ + int SGSN_NAME = 2409; + + /** + * SLh (3GPP TS 29.173) SGSN-Realm AVP code + */ + int SGSN_REALM = 2410; + + /** + * SLh (3GPP TS 29.173) RIA-Flags AVP code + */ + int RIA_FLAGS = 2411; + + /** + * SLh (3GPP TS 29.173) SGSN-Number AVP code (reused from 3GPP TS 29.272, MME - SGSN interface) + */ + int SGSN_NUMBER = 1489; + + /** + * SLh (3GPP TS 29.173) GMLC-Number AVP code (reused from 3GPP TS 29.272, MME - SGSN interface) + */ + int GMLC_NUMBER = 1474; + + /** + * SLh (3GPP TS 29.173) 3GPP-AAA-Server-Name AVP code (reused from 3GPP TS 29.273, 3GPP AAA EPS interface) + */ + int TGPP_AAA_SERVER_NAME = 318; + + // SLh re-used Diameter AVPs: + // MSISDN 3GPP TS 29.329; + // SGSN-Number 3GPP TS 29.272; + // Supported-Features 3GPP TS 29.229; + // Feature-List-ID 3GPP TS 29.229; + // Feature-List 3GPP TS 29.229; + // GMLC-Number 3GPP TS 29.272; + // 3GPP-AAA-Server-Name 3GPP TS 29.273 + + /********************************************************/ + /*** SLg interface (GMLC - MME) AVPs (3GPP TS 29.172) ***/ + /*** Diameter ELP Application (EPC LCS Protocol) ***/ + /********************************************************/ + + /** + * SLg (3GPP TS 29.172) SLg-Location-Type AVP code + */ + int SLG_LOCATION_TYPE = 2500; + + /** + * SLg (3GPP TS 29.172) LCS-EPS-Client-Name AVP code + */ + int LCS_EPS_CLIENT_NAME = 2501; + + /** + * SLg (3GPP TS 29.172) LCS_Requestor_Name AVP code + */ + int LCS_REQUESTOR_NAME = 2502; + + /** + * SLg (3GPP TS 29.172) LCS-Priority AVP code + */ + int LCS_PRIORITY = 2503; + + /** + * SLg (3GPP TS 29.172) LCS-QoS AVP code + */ + int LCS_QOS = 2504; + + /** + * SLg (3GPP TS 29.172) Horizontal-Accuracy AVP code + */ + int HORIZONTAL_ACCURACY = 2505; + + /** + * SLg (3GPP TS 29.172) Vertical-Accuracy AVP code + */ + int VERTICAL_ACCURACY = 2506; + + /** + * SLg (3GPP TS 29.172) Vertical-Requested AVP code + */ + int VERTICAL_REQUESTED = 2507; + + /** + * SLg (3GPP TS 29.172) Velocity-Requested AVP code + */ + int VELOCITY_REQUESTED = 2508; + + /** + * SLg (3GPP TS 29.172) Response-Time AVP code + */ + int RESPONSE_TIME = 2509; + + /** + * SLg (3GPP TS 29.172) Supported-GAD-Shapes AVP code + */ + int SUPPORTED_GAD_SHAPES = 2510; + + /** + * SLg (3GPP TS 29.172) LCS-Codeword AVP code + */ + int LCS_CODEWORD = 2511; + + /** + * SLg (3GPP TS 29.172) LCS-Privacy-Check AVP code + */ + int LCS_PRIVACY_CHECK = 2512; + + /** + * SLg (3GPP TS 29.172) Accuracy-Fulfilment-Indicator AVP code + */ + int ACCURACY_FULFILMENT_INDICATOR = 2513; + + /** + * SLg (3GPP TS 29.172) Age-Of-Location-Estimate AVP code + */ + int AGE_OF_LOCATION_ESTIMATE = 2514; + + /** + * SLg (3GPP TS 29.172) Velocity-Estimate 2515 AVP code + */ + int VELOCITY_ESTIMATE = 2515; + + /** + * SLg (3GPP TS 29.172) EUTRAN-Positioning-Data AVP code + */ + int EUTRAN_POSITIONING_DATA = 2516; + + /** + * SLg (3GPP TS 29.172) ECGI AVP code + */ + int ECGI = 2517; + + /** + * SLg (3GPP TS 29.172) Location_Event AVP code + */ + int LOCATION_EVENT = 2518; + + /** + * SLg (3GPP TS 29.172) Pseudonym-Indicator + */ + int PSEUDONYM_INDICATOR = 2519; + + /** + * SLg (3GPP TS 29.172) LCS-Service-Type-ID AVP Code + */ + int LCS_SERVICE_TYPE_ID = 2520; + + /** + * SLg (3GPP TS 29.172) LCS-Privacy-Check-Non-Session AVP Code + */ + int LCS_PRIVACY_CHECK_NON_SESSION = 2521; + + /** + * SLg (3GPP TS 29.172) LCS-Privacy-Check-Session AVP Code + */ + int LCS_PRIVACY_CHECK_SESSION = 2522; + + /** + * SLg (3GPP TS 29.172) LCS-QoS-Class AVP Code + */ + int LCS_QOS_CLASS = 2523; + + /** + * SLg (3GPP TS 29.172) GERAN-Positioning-Info AVP Code + */ + int GERAN_POSITIONING_INFO = 2524; + + /** + * SLg (3GPP TS 29.172) GERAN-Positioning-Data AVP Code + */ + int GERAN_POSITIONING_DATA = 2525; + + /** + * SLg (3GPP TS 29.172) GERAN-GANSS-Positioning-Data AVP Code + */ + int GERAN_GANSS_POSITIONING_DATA = 2526; + + /** + * SLg (3GPP TS 29.172) UTRAN-Positioning-Info AVP Code + */ + int UTRAN_POSITIONING_INFO = 2527; + + /** + * SLg (3GPP TS 29.172) UTRAN-Positioning-Data AVP Code + */ + int UTRAN_POSITIONING_DATA = 2528; + + /** + * SLg (3GPP TS 29.172) UTRAN-GANSS-Positioning-Data AVP Code + */ + int UTRAN_GANSS_POSITIONING_DATA = 2529; + + /** + * SLg (3GPP TS 29.172) LRR-Flags AVP Code + */ + int LRR_FLAGS = 2530; + + /** + * SLg (3GPP TS 29.172) LCS-Reference-Number AVP Code + */ + int LCS_REFERENCE_NUMBER = 2531; + + /** + * SLg (3GPP TS 29.172) Deferred-Location-Type AVP Code + */ + int DEFERRED_LOCATION_TYPE = 2532; + + /** + * SLg (3GPP TS 29.172) Area-Event-Info AVP Code + */ + int AREA_EVENT_INFO = 2533; + + /** + * SLg (3GPP TS 29.172) Area-Definition AVP Code + */ + int AREA_DEFINITION = 2534; + + /** + * SLg (3GPP TS 29.172) Area AVP Code + */ + int AREA = 2535; + + /** + * SLg (3GPP TS 29.172) Area-Type AVP Code + */ + int AREA_TYPE = 2536; + + /** + * SLg (3GPP TS 29.172) Area-Identification AVP Code + */ + int AREA_IDENTIFICATION = 2537; + + /** + * SLg (3GPP TS 29.172) Occurrence-Info AVP Code + */ + int OCCURRENCE_INFO = 2538; + + /** + * SLg (3GPP TS 29.172) Interval-Time AVP Code + */ + int INTERVAL_TIME = 2539; + + /** + * SLg (3GPP TS 29.172) Periodic-LDR-Information AVP Code + */ + int PERIODIC_LDR_INFORMATION = 2540; + + /** + * SLg (3GPP TS 29.172) Reporting-Amount AVP Code + */ + int REPORTING_AMOUNT = 2541; + + /** + * SLg (3GPP TS 29.172) Reporting-Interval AVP Code + */ + int REPORTING_INTERVAL = 2542; + + /** + * SLg (3GPP TS 29.172) Reporting-PLMN-List AVP Code + */ + int REPORTING_PLMN_LIST = 2543; + + /** + * SLg (3GPP TS 29.172) PLMN-ID-List AVP Code + */ + int PLMN_ID_LIST = 2544; + + /** + * SLg (3GPP TS 29.172) PLR-Flags AVP Code + */ + int PLR_FLAGS = 2545; + + /** + * SLg (3GPP TS 29.172) PLA-Flags AVP Code + */ + int PLA_FLAGS = 2546; + + /** + * SLg (3GPP TS 29.172) Deferred-MT-LR-Data AVP Code + */ + int DEFERRED_MT_LR_DATA = 2547; + + /** + * SLg (3GPP TS 29.172) Termination-Cause AVP Code; + */ + int TERMINATION_CAUSE_LCS = 2548; + + /** + * SLg (3GPP TS 29.172) LRA-Flags AVP Code + */ + int LRA_FLAGS = 2549; + + /** + * SLg (3GPP TS 29.172) Periodic-Location-Support-Indicator AVP Code + */ + int PERIODIC_LOCATION_SUPPORT_INDICATOR = 2550; + + /** + * SLg (3GPP TS 29.172) + */ + int PRIORITIZED_LIST_INDICATOR = 2551; + + /** + * SLg (3GPP TS 29.172)ESMLC-Cell-Info AVP Code + */ + int ESMLC_CELL_INFO = 2552; + + /** + * SLg (3GPP TS 29.172) Cell-Portion-ID AVP Code + */ + int CELL_PORTION_ID = 2553; + + /** + * SLg (3GPP TS 29.172) 1xRTT-RCID AVP Code + */ + int ONEXRTT_RCID = 2554; + + /** + * SLg (3GPP TS 29.172) Civic-Address AVP Code + */ + int CIVIC_ADDRESS = 2556; + + /** + * SLg (3GPP TS 29.172) Barometric-Pressure AVP Code + */ + int BAROMETRIC_PRESSURE = 2557; + + /** + * SLg (3GPP TS 29.172) UTRAN-Additional-Positioning-Data AVP Code + */ + int UTRAN_ADDITIONAL_POSITIONING_DATA = 2558; + + /** + * SLg (3GPP TS 29.172) Service-Selection AVP Code (reused from 3GPP TS 29.272 & IETF RFC 5778) + */ + int SERVICE_SELECTION = 493; + + /** + * SLg (3GPP TS 29.172) Cell-Global-Identity AVP Code (reused from 3GPP TS 29.272) + */ + int CELL_GLOBAL_IDENTITY = 1604; + + /** + * SLg (3GPP TS 29.172) Visited-PLMN-Id AVP Code (reused from 3GPP TS 29.272) + */ + int VISITED_PLMN_ID = 1407; + + /** + * SLg (3GPP TS 29.172) Service-Area-Identity AVP Code (reused from 3GPP TS 29.272) + */ + int SERVICE_AREA_IDENTITY = 1607; + + // Diameter ELP Application (SLg) reused AVPs: + // LCS-Format-Indicator 1237 3GPP TS 32.299; + // LCS-Name-String 1238 3GPP TS 2.299; + // LCS-Client-Type 1241 3GPP TS 32.299 + // LCS-Requestor-Id-String 1240 3GPP TS 32.299; + // Location-Estimate 1242 3GPP TS 32.299; + // IMEI 1402 3GPP TS 29.272; + // MSISDN 701 3GPP TS 29.329; + // Service-Selection 493 3GPP TS 29.272, IETF RFC 5778 + // User-Name 1 IETF RFC 3588; + // Supported-Features 628 3GPP TS 29.229; + // Feature-List-ID 629 3GPP TS 29.229; + // Feature-List 630 3GPP TS 29.229; + // Serving-Node 2401 3GPP TS 29.173; + // Cell-Global-Identity 1604 3GPP TS 29.272; + // Service-Area-Identity 1607 3GPP TS 29.272; + // GMLC-Address 2405 3GPP TS 29.173; + // Visited-PLMN-Id 1407 3GPP TS 29.272 /** * @return the AVP code. diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSession.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSession.java new file mode 100644 index 000000000..f0e6c7802 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSession.java @@ -0,0 +1,85 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slg; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateMachine; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ClientSLgSession extends AppSession, StateMachine { + + /** + * Send Provide-Location-Request to server + * + * @param request Provide-Location-Request event instance + * @throws InternalException The InternalException signals that internal error is occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void sendProvideLocationRequest(ProvideLocationRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + /** + * Send Location-Report-Request to server + * + * @param request Location-Report-Request event instance + * @throws InternalException The InternalException signals that internal error is occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void sendLocationReportRequest(LocationReportRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSessionListener.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSessionListener.java new file mode 100644 index 000000000..3d3cf3ae9 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ClientSLgSessionListener.java @@ -0,0 +1,73 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slg; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ClientSLgSessionListener { + + void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + void doProvideLocationAnswerEvent(ClientSLgSession session, ProvideLocationRequest request, ProvideLocationAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + void doLocationReportAnswerEvent(ClientSLgSession session, LocationReportRequest request, LocationReportAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSession.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSession.java new file mode 100644 index 000000000..f3f7c2027 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSession.java @@ -0,0 +1,85 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slg; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateMachine; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ServerSLgSession extends AppSession, StateMachine { + + /** + * Send Provide-Location-Answer to client + * + * @param answer Provide-Location-Answer event instance + * @throws InternalException The InternalException signals that internal error is occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void sendProvideLocationAnswer(ProvideLocationAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + /** + * Send Location-Report-Answer to client + * + * @param answer Location-Report-Answer event instance + * @throws InternalException The InternalException signals that internal error is occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void sendLocationReportAnswer(LocationReportAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} \ No newline at end of file diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSessionListener.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSessionListener.java new file mode 100644 index 000000000..8149fed73 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/ServerSLgSessionListener.java @@ -0,0 +1,70 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slg; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ServerSLgSessionListener { + + void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + void doProvideLocationRequestEvent(ServerSLgSession session, ProvideLocationRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + void doLocationReportRequestEvent(ServerSLgSession session, LocationReportRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; +} \ No newline at end of file diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportAnswer.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportAnswer.java new file mode 100644 index 000000000..12d99e092 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportAnswer.java @@ -0,0 +1,70 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.jdiameter.api.slg.events; + +import org.jdiameter.api.app.AppAnswerEvent; + +/** + * @author Fernando Mendioroz + * + */ + +/* + * As for 3GPP TS 29.172 v13.0.0, Subscriber Location Report operation is used by an MME or SGSN to provide the location of a + * target UE to a GMLC, when a request for location has been implicitly issued or when a Delayed Location Reporting is triggered + * after receipt of a request for location for a UE transiently not reachable. + * + * The Location-Report-Answer (LRA) command, indicated by the Command-Code field set to 8388621 and the "R" bit cleared in the + * Command Flags field, is sent by the GMLC to the MME or SGSN in response to the Location-Report-Request command (Subscriber + * Location Report operation answer) + */ + +public interface LocationReportAnswer extends AppAnswerEvent{ + + String _SHORT_NAME = "LRA"; + String _LONG_NAME = "Location-Report-Answer"; + + int code = 8388621; + + boolean isGMLCAddressAvpPresent(); + java.net.InetAddress getGMLCAddress(); + + boolean isLRAFlagsAvpPresent(); + long getLRAFLags(); + + boolean isReportingPLMNListAvpPresent(); + // Reporting-PLMN-List AVP of type grouped, includes: + // PLMN-ID-List, Prioritized-List-Indicator + boolean isPrioritizedListIndicatorAvpPresent(); + int getPrioritizedListIndicator(); + boolean isPLMNIDListAvpPresent(); + // PLMN-ID-List AVP of type grouped, includes: + // Visited-PLMN-Id, Periodic-Location-Support-Indicator + boolean isVisitedPLMNIdAvpPresent(); + byte[] getVisitedPLMNId(); + boolean isPeriodicLocationSupportIndicatorAvpPresent(); + int getPeriodicLocationSupportIndicator(); + + boolean isLCSReferenceNumberAvpPresent(); + byte[] getLCSReferenceNumber(); + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportRequest.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportRequest.java new file mode 100644 index 000000000..1c6566a72 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/LocationReportRequest.java @@ -0,0 +1,192 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.jdiameter.api.slg.events; + +import org.jdiameter.api.app.AppRequestEvent; + +/** + * @author Fernando Mendioroz + * + */ + +/* + * As for 3GPP TS 29.172 v13.0.0, Subscriber Location Report operation is used by an MME or SGSN to provide the location of a + * target UE to a GMLC, when a request for location has been implicitly issued or when a Delayed Location Reporting is triggered + * after receipt of a request for location for a UE transiently not reachable. + * + * The Location-Report-Request (LRR) command, indicated by the Command-Code field set to 8388621 and the "R" bit set in the + * Command Flags field, is sent by the MME or SGSN in order to provide subscriber location data to the GMLC (Subscriber Location + * Report operation request) + */ + +public interface LocationReportRequest extends AppRequestEvent { + + String _SHORT_NAME = "LRR"; + String _LONG_NAME = "Location-Report-Request"; + + int code = 8388621; + + boolean isLocationEventAvpPresent(); + int getLocationEvent(); + + boolean isUserNameAvpPresent(); // Mapped IE: IMSI + String getUserName(); // Mapped IE: IMSI + + boolean isMSISDNAvpPresent(); + byte[] getMSISDN(); + + boolean isIMEIAvpPresent(); + String getIMEI(); + + boolean isLCSEPSClientNameAvpPresent(); + // LCS-EPS-Client-Name AVP of type grouped, includes: + // LCS-Name-String, LCS-Format-Indicator + boolean isLSCNameStringAvpPresent(); + String getLSCNameString(); + boolean isLCSFormatIndicatorAvpPresent(); + int getLCSFormatIndicator(); + + boolean isLocationEstimateAvpPresent(); + byte[] getLocationEstimate(); + + boolean isAccuracyFulfilmentIndicatorAvpPresent(); + int getAccuracyFulfilmentIndicator(); + + boolean isAgeOfLocationEstimateAvpPresent(); + long getAgeOfLocationEstimate(); + + boolean isVelocityEstimateAvpPresent(); + byte[] getVelocityEstimate(); + + boolean isEUTRANPositioningDataAvpPresent(); + byte[] getEUTRANPositioningData(); + + boolean isECGIAvpPresent(); + byte[] getECGI(); + + boolean isGERANPositioningInfoAvpPresent(); + // GERAN-Positioning-Info AVP of type grouped, includes: + // GERAN-Positioning-Data, GERAN-GANSS-Positioning-Data + boolean isGERANPositioningDataAvpPresent(); + byte[] getGERANPositioningData(); + boolean isGERANGANSSPositioningDataAvpPresent(); + byte[] getGERANGANSSPositioningData(); + + boolean isCellGlobalIdentityAvpPresent(); + byte[] getCellGlobalIdentity(); + + boolean isUTRANPositioningInfoAvpPresent(); + // UTRAN-Positioning-Info AVP of type grouped, includes: + // UTRAN-Positioning-Data, UTRAN-GANSS-Positioning-Data + boolean isUTRANPositioningDataAvpPresent(); + byte[] getUTRANPositioningData(); + boolean isUTRANGANSSPositioningDataAvpPresent(); + byte[] getUTRANGANSSPositioningData(); + + boolean isServiceAreaIdentityAvpPresent(); + byte[] getServiceAreaIdentity(); + + boolean isLCSServiceTypeIDAvpPresent(); + long getLCSServiceTypeID(); + + boolean isPseudonymIndicatorAvpPresent(); + int getPseudonymIndicator(); + + boolean isLCSQoSAvpPresent(); + // LCS-QoS AVP of type grouped, includes: + // LCS-QoS-Class, Horizontal-Accuracy, Vertical-Accuracy + // Vertical-Requested, Response-Time + boolean isLCSQoSClassAvpPresent(); + int getLCSQoSClass(); + boolean isHorizontalAccuracyAvpPresent(); + long getHorizontalAccuracy(); + boolean isVerticalAccuracyAvpPresent(); + long getVerticalAccuracy(); + boolean isVerticalRequestedAvpPresent(); + int getVerticalRequested(); + boolean isResponseTimeAvpPresent(); + int getResponseTime(); + + boolean isServingNodeAvpPresent(); + // [ Serving-Node ] IE: Target Serving Node Identity + // Serving-Node AVP of type grouped, includes: + // SGSN-Number, SGSN-Name, SGSN-Realm. + // MME-Name, MME-Realm + // MSC-Number + // 3GPP-AAA-Server-Name, LCS-Capabilities-Sets, GMLC-Address + boolean isSGSNNumberAvpPresent(); + byte[] getSGSNNumber(); + boolean isSGSNNameAvpPresent(); + String getSGSNName(); + boolean isSGSNRealmAvpPresent(); + String getSGSNRealm(); + boolean isMMENameAvpPresent(); + String getMMEName(); + boolean isMMERealmAvpPresent(); + String getMMERealm(); + boolean isMSCNumberAvpPresent(); + byte[] getMSCNumber(); + boolean is3GPPAAAServerNameAvpPresent(); + String get3GPPAAAServerName(); + boolean isLCSCapabilitiesSetsAvpPresent(); + long getLCSCapabilitiesSets(); + boolean isGMLCAddressAvpPresent(); + java.net.InetAddress getGMLCAddress(); + + boolean isLRRFlagsAvpPresent(); + long getLRRFLags(); + + boolean isLCSReferenceNumberAvpPresent(); + byte[] getLCSReferenceNumber(); + + boolean isDeferredMTLRDataAvpPresent(); + // Deferred-MT-LR-Data AVP of type grouped, includes: + // Deferred-Location-Type, Termination-Cause. + boolean isDeferredLocationTypeAvpPresent(); + long getDeferredLocationType(); + boolean isTerminationCauseAvpPresent(); + long getTerminationCause(); + + boolean isHGMLCAddressAvpPresent(); // IE: H-GMLC Address mapped to GMLC-Address AVP + java.net.InetAddress getHGMLCAddress(); + + boolean isPeriodicLDRInfoAvpPresent(); + // Periodic-LDR-Info AVP of type grouped, includes: + // Reporting-Amount, Reporting-Interval + boolean isReportingAmountAvpPresent(); + long getReportingAmount(); + boolean isReportingIntervalAvpPresent(); + long getReportingInterval(); + + boolean isESMLCCellInfoAvpPresent(); + long getCellPortionId(); + + boolean is1xRTTRCIDAvpPresent(); + byte[] get1xRTTRCID(); + + boolean isCivicAddressAvpPresent(); + String getCivicAddress(); + + boolean isBarometricPressureAvpPresent(); + long getBarometricPressure(); + +} \ No newline at end of file diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationAnswer.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationAnswer.java new file mode 100644 index 000000000..71a524da5 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationAnswer.java @@ -0,0 +1,129 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.jdiameter.api.slg.events; + +import org.jdiameter.api.app.AppAnswerEvent; + +/** + * @author Fernando Mendioroz + * + */ + +/* + * As for 3GPP TS 29.172 v13.0.0, the Provide Subscriber Location operation is used by a GMLC to request the location of a + * target UE from the MME or SGSN at any time, as part of EPC-MT-LR (Evolved Packet Core Mobile Terminated Location Request) or + * PS-MT-LR (Packet Switched Mobile Terminated Location Request) positioning procedures. The response contains a location + * estimate of the target UE and other additional information. This operation is also used by a GMLC to request the location of + * the target UE from the SGSN at any time, as part of deferred MT-LR procedure. The response contains the acknowledgment of the + * receipt of the request and other additional information. + * + * The Provide-Location-Answer (PLA) command, indicated by the Command-Code field set to 8388620 and the "R" bit cleared in the + * Command Flags field, is sent by the MME or SGSN to the GMLC in response to the Provide-Location-Request command (Provide + * Subscriber Location operation answer) + */ + +public interface ProvideLocationAnswer extends AppAnswerEvent{ + + String _SHORT_NAME = "PLA"; + String _LONG_NAME = "Provide-Location-Answer"; + + int code = 8388620; + + boolean isLocationEstimateAvpPresent(); + byte[] getLocationEstimate(); + + boolean isAccuracyFulfilmentIndicatorAvpPresent(); + int getAccuracyFulfilmentIndicator(); + + boolean isAgeOfLocationEstimateAvpPresent(); + long getAgeOfLocationEstimate(); + + boolean isVelocityEstimateAvpPresent(); + byte[] getVelocityEstimate(); + + boolean isEUTRANPositioningDataAvpPresent(); + byte[] getEUTRANPositioningData(); + + boolean isECGIAvpPresent(); + byte[] getECGI(); + + boolean isGERANPositioningInfoAvpPresent(); + // GERAN-Positioning-Info AVP of type grouped, includes: + // GERAN-Positioning-Data, GERAN-GANSS-Positioning-Data + boolean isGERANPositioningDataAVPPresent(); + byte[] getGERANPositioningData(); + boolean isGERANGANSSPositioningDataAVPPresent(); + byte[] getGERANGANSSPositioningData(); + + boolean isCellGlobalIdentityAvpPresent(); + byte[] getCellGlobalIdentity(); + + boolean isUTRANPositioningInfoAvpPresent(); + // UTRAN-Positioning-Info AVP of type grouped, includes: + // UTRAN-Positioning-Data, UTRAN-GANSS-Positioning-Data + boolean isUTRANPositioningDataAVPPresent(); + byte[] getUTRANPositioningData(); + boolean isUTRANGANSSPositioningDataAVPPresent(); + byte[] getUTRANGANSSPositioningData(); + + boolean isServiceAreaIdentityAvpPresent(); + byte[] getServiceAreaIdentity(); + + boolean isServingNodeAvpPresent(); + // [ Serving-Node ] IE: Target Serving Node Identity + // Serving-Node AVP of type grouped, includes: + // SGSN-Number, SGSN-Name, SGSN-Realm. + // MME-Name, MME-Realm + // MSC-Number + // 3GPP-AAA-Server-Name, LCS-Capabilities-Sets, GMLC-Address + boolean isSGSNNumberAvpPresent(); + byte[] getSGSNNumber(); + boolean isSGSNNameAvpPresent(); + String getSGSNName(); + boolean isSGSNRealmAvpPresent(); + String getSGSNRealm(); + boolean isMMENameAvpPresent(); + String getMMEName(); + boolean isMMERealmAvpPresent(); + String getMMERealm(); + boolean isMSCNumberAvpPresent(); + byte[] getMSCNumber(); + boolean is3GPPAAAServerNameAvpPResent(); + String get3GPPAAAServerName(); + boolean isLCSCapabilitiesSetsAvpPresent(); + long getLCSCapabilitiesSets(); + boolean isGMLCAddressAvpPresent(); + java.net.InetAddress getGMLCAddress(); + + boolean isPLAFlagsAvpPresent(); + long getPLAFlags(); + + boolean isESMLCCellInfoAvpPresent(); + long getCellPortionId(); + + boolean isCivicAddressAvpPresent(); + String getCivicAddress(); + + boolean isBarometricPressureAvpPresent(); + long getBarometricPressure(); + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationRequest.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationRequest.java new file mode 100644 index 000000000..f8b8bf4ad --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slg/events/ProvideLocationRequest.java @@ -0,0 +1,174 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.jdiameter.api.slg.events; + +import org.jdiameter.api.app.AppRequestEvent; + +/** + * @author Fernando Mendioroz + * + */ + +/* + * As for 3GPP TS 29.172 v13.0.0, the Provide Subscriber Location operation is used by a GMLC to request the location of a + * target UE from the MME or SGSN at any time, as part of EPC-MT-LR (Evolved Packet Core Mobile Terminated Location Request) or + * PS-MT-LR (Packet Switched Mobile Terminated Location Request) positioning procedures. The response contains a location + * estimate of the target UE and other additional information. This operation is also used by a GMLC to request the location of + * the target UE from the SGSN at any time, as part of deferred MT-LR procedure. The response contains the acknowledgment of the + * receipt of the request and other additional information. + * + * The Provide-Location-Request (PLR) command, indicated by the Command-Code field set to 8388620 and the "R" bit set in the + * Command Flags field, is sent by the GMLC in order to request subscriber location to the MME or SGSN (Provide Subscriber + * Location operation request) + */ + +public interface ProvideLocationRequest extends AppRequestEvent { + + String _SHORT_NAME = "PLR"; + String _LONG_NAME = "Provide-Location-Request"; + + int code = 8388620; + + boolean isSLgLocationTypeAvpPresent(); + int getSLgLocationType(); + + boolean isUserNameAvpPresent(); // Mapped IE: IMSI + String getUserName(); // Mapped IE: IMSI + + boolean isMSISDNAvpPresent(); + byte[] getMSISDN(); + + boolean isIMEIAvpPresent(); + String getIMEI(); + + boolean isLCSEPSClientNameAvpPresent(); + // LCS-EPS-Client-Name AVP of type grouped, includes: + // LCS-Name-String, LCS-Format-Indicator + boolean isLSCNameStringAvpPresent(); + String getLSCNameString(); + boolean isLCSFormatIndicatorAvpPresent(); + int getLCSFormatIndicator(); + + boolean isLCSCLientTypeAvpPresent(); + int getLCSClientType(); + + boolean isLCSRequestorNamePresent(); + // LCS-Requestor-NAme AVP of type grouped, includes: + // LCS-Requestor-Id-String, LCS-Format-Indicator + boolean isLCSRequestorIdStringAvpPresent(); + String getLCSRequestorIdString(); + boolean isReqLCSFormatIndicatorAvpPresent(); + int getReqLCSFormatIndicator(); + + boolean isLCSPriorityPresent(); + long getLCSPriority(); + + boolean isLCSQoSAvpPresent(); + // LCS-QoS AVP of type grouped, includes: + // LCS-QoS-Class, Horizontal-Accuracy, Vertical-Accuracy + // Vertical-Requested, Response-Time + boolean isLCSQoSClassAvpPresent(); + int getLCSQoSClass(); + boolean isHorizontalAccuracyAvpPresent(); + long getHorizontalAccuracy(); + boolean isVerticalAccuracyAvpPresent(); + long getVerticalAccuracy(); + boolean isVerticalRequestedAvpPresent(); + int getVerticalRequested(); + boolean isResponseTimeAvpPresent(); + int getResponseTime(); + + boolean isVelocityRequestedAvpPresent(); + int getVelocityRequested(); + + boolean isSupportedGADShapesAvpPresent(); + long getSupportedGADSahpes(); + + boolean isLSCServiceTypeIdAvpPresent(); + long getLSCServiceTypeId(); + + boolean isLCSCodewordAvpPresent(); + String getLCSCodeword(); + + boolean isServiceSelectionAvpPresent(); + String getServiceSelection(); // IE: APN + + boolean isLCSPrivacyCheckSessionAvpPresent(); // IE: Session-Related Privacy Check + // LCS-Privacy-Check-Session of type grouped, includes + // LCS-Privacy-Check + boolean isLCSPrivacyCheckAvpPresent(); + int getLCSPrivacyCheck(); + + boolean isLCSPrivacyCheckNonSessionAvpPresent(); // IE: Non-Session-Related Privacy Check + // LCS-Privacy-Check-Non-Session of type grouped, includes + // LCS-Privacy-Check + boolean isLCSPrivacyCheckNSAvpPresent(); + int getLCSPrivacyCheckNS(); + + boolean isDeferredLocationTypeAvpPresent(); + long getDeferredLocationType(); + + boolean isLCSReferenceNumberAvpPresent(); + byte[] getLCSReferenceNumber(); + + boolean isAreaEventInfoAvpPresent(); + // Area-Event-Info AVP of type grouped, includes: + // Area-Definition, Occurrence-Info, Interval-Time + boolean isOccurrenceInfoAvpPresent(); + int getOccurrenceInfo(); + boolean isIntervalTimeAvpPresent(); + long getIntervalTime(); + boolean isAreaDefinitionAvpPresent(); + // Area-Definition AVP of type grouped, includes: + // Area-Type, Area-Identification + boolean isAreaTypeAvpPresent(); + long getAreaType(); + boolean isAreaIdentificationAvpPresent(); + byte[] getAreaIdentification(); + + boolean isGMLCAddressAvpPresent(); + java.net.InetAddress getGMLCAddress(); + + boolean isPLRFlagsAvpPresent(); + long getPLRFLags(); + + boolean isPeriodicLDRInfoAvpPresent(); + // Periodic-LDR-Info AVP of type grouped, includes: + // Reporting-Amount, Reporting-Interval + boolean isReportingAmountAvpPresent(); + long getReportingAmount(); + boolean isReportingIntervalAvpPresent(); + long getReportingInterval(); + + boolean isReportingPLMNListAvpPresent(); + // Reporting-PLMN-List AVP of type grouped, includes: + // PLMN-ID-List, Prioritized-List-Indicator + boolean isPrioritizedListIndicatorAvpPresent(); + int getPrioritizedListIndicator(); + boolean isPLMNIDListAvpPresent(); + // PLMN-ID-List AVP of type grouped, includes: + // Visited-PLMN-Id, Periodic-Location-Support-Indicator + boolean isVisitedPLMNIdAvpPresent(); + byte[] getVisitedPLMNId(); + boolean isPeriodicLocationSupportIndicatorAvpPresent(); + int getPeriodicLocationSupportIndicator(); +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSession.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSession.java new file mode 100644 index 000000000..dc98bd7bd --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSession.java @@ -0,0 +1,73 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slh; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateMachine; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ClientSLhSession extends AppSession, StateMachine { + + /** + * Send LCS-Routing-Info-Request to server + * + * @param request LCS-Routing-Info-Request event instance + * @throws InternalException The InternalException signals that internal error is occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + + void sendLCSRoutingInfoRequest(LCSRoutingInfoRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSessionListener.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSessionListener.java new file mode 100644 index 000000000..3213720f4 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ClientSLhSessionListener.java @@ -0,0 +1,69 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slh; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; + + +/** + * @author Fernando Mendioroz + * + */ + +public interface ClientSLhSessionListener { + + void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + void doLCSRoutingInfoAnswerEvent(ClientSLhSession session, LCSRoutingInfoRequest request, LCSRoutingInfoAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSession.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSession.java new file mode 100644 index 000000000..9e86782cf --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSession.java @@ -0,0 +1,72 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slh; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateMachine; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ServerSLhSession extends AppSession, StateMachine { + + /** + * Send LCS-Routing-Info-Answer to client + * + * @param answer LCS-Routing-Info-Answer event instance + * @throws InternalException The InternalException signals that internal error is occurred. + * @throws IllegalDiameterStateException The IllegalStateException signals that session has incorrect state (invalid). + * @throws RouteException The NoRouteException signals that no route exist for a given realm. + * @throws OverloadException The OverloadException signals that destination host is overloaded. + */ + void sendLCSRoutingInfoAnswer(LCSRoutingInfoAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} \ No newline at end of file diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSessionListener.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSessionListener.java new file mode 100644 index 000000000..f7087776d --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/ServerSLhSessionListener.java @@ -0,0 +1,67 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.api.slh; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ServerSLhSessionListener { + + void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + + void doLCSRoutingInfoRequestEvent(ServerSLhSession session, LCSRoutingInfoRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException; + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoAnswer.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoAnswer.java new file mode 100644 index 000000000..ee5e56e98 --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoAnswer.java @@ -0,0 +1,132 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.jdiameter.api.slh.events; + +import org.jdiameter.api.app.AppAnswerEvent; + +/** + * @author Fernando Mendioroz + * + */ + +/* + * As for 3GPP TS 29.173 v13.0.0, the LCS-Routing-Info-Answer (RIA) command, indicated by the Command-Code field set to 8388622 + * and the "R" bit cleared in the Command Flags field, is sent from HSS to GMLC. The procedure invoked by the GMLC is used for + * retrieving routing information for LCS (Location Services) for a specified user from the HSS via a LCS-Routing-Info-Request + * (RIR) command. + * + */ +public interface LCSRoutingInfoAnswer extends AppAnswerEvent { + + String _SHORT_NAME = "RIA"; + String _LONG_NAME = "LCS-Routing-Info-Answer"; + + int code = 8388622; + + boolean isUserNameAVPPresent(); // Mapped IE: IMSI + String getUserName(); // Mapped IE: IMSI + + boolean isMSISDNAVPPresent(); + byte[] getMSISDN(); + + boolean isLMSIAVPPresent(); + byte[] getLMSI(); + + boolean isServingNodeAVPPresent(); + // Serving-Node AVP of type grouped, includes: + // SGSN-Number, SGSN-Name, SGSN-Realm + // MME-Name, MME-Realm + // MSC-Number + // 3GPP-AAA-Server-Name + // LCS-Capabilities-Sets + // GMLC-Address + + boolean isSGSNNumberAVPPresent(); + byte[] getSGSNNumber(); + + boolean isSGSNNameAVPPresent(); + String getSGSNName(); + + boolean isSGSNRealmAVPPresent(); + String getSGSNRealm(); + + boolean isMMENameAVPPresent(); + String getMMEName(); + + boolean isMMERealmAVPPresent(); + String getMMERealm(); + + boolean isMSCNumberAVPPresent(); + byte[] getMSCNumber(); + + boolean is3GPPAAAServerNameAVPPresent(); + String get3GPPAAAServerName(); + + boolean isLCSCapabilitiesSetsAVPPresent(); + long getLCSCapabilitiesSets(); + + boolean isGMLCAddressAVPPresent(); + java.net.InetAddress getGMLCAddress(); + + boolean isAdditionalServingNodeAVPPresent(); + // Serving-Node AVP of type grouped, includes: + // SGSN-Number, SGSN-Name, SGSN-Realm + // MME-Name, MME-Realm + // MSC-Number + // 3GPP-AAA-Server-Name + // LCS-Capabilities-Sets + // GMLC-Address + + boolean isAdditionalSGSNNumberAVPPresent(); + byte[] getAdditionalSGSNNumber(); + + boolean isAdditionalSGSNNameAVPPresent(); + String getAdditionalSGSNName(); + + boolean isAdditionalSGSNRealmAVPPresent(); + String getAdditionalSGSNRealm(); + + boolean isAdditionalMMENameAVPPresent(); + String getAdditionalMMEName(); + + boolean isAdditionalMMERealmAVPPresent(); + String getAdditionalMMERealm(); + + boolean isAdditionalMSCNumberAVPPresent(); + byte[] getAdditionalMSCNumber(); + + boolean isAdditional3GPPAAAServerNameAVPPresent(); + String getAdditional3GPPAAAServerName(); + + boolean isAdditionalLCSCapabilitiesSetsAVPPresent(); + long getAdditionalLCSCapabilitiesSets(); + + boolean isAdditionalGMLCAddressAVPPresent(); + java.net.InetAddress getAdditionalGMLCAddress(); + + boolean isPPRAddressAVPPresent(); + java.net.InetAddress getPPRAddress(); + + boolean isRIAFlagsAVPPresent(); + long getRIAFLags(); + +} diff --git a/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoRequest.java b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoRequest.java new file mode 100644 index 000000000..71f97885a --- /dev/null +++ b/core/jdiameter/api/src/main/java/org/jdiameter/api/slh/events/LCSRoutingInfoRequest.java @@ -0,0 +1,53 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, Telestax Inc and individual contributors + * by the @authors tag. + * + * 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.jdiameter.api.slh.events; + +import org.jdiameter.api.app.AppRequestEvent; + +/** + * @author Fernando Mendioroz + * + */ + +/* + * As for 3GPP TS 29.173 v13.0.0, the LCS-Routing-Info-Request (RIR) command, indicated by the Command-Code field set to 8388622 + * and the "R" bit set in the Command Flags field, is sent from GMLC to HSS. The procedure invoked by the GMLC is used for + * retrieving routing information for LCS (Location Services) for a specified user from the HSS. + * + */ +public interface LCSRoutingInfoRequest extends AppRequestEvent { + + String _SHORT_NAME = "RIR"; + String _LONG_NAME = "LCS-Routing-Info-Request"; + + int code = 8388622; + + boolean isUserNameAVPPresent(); // Mapped IE: IMSI + String getUserName(); // Mapped IE: IMSI + + boolean isMSISDNAVPPresent(); + byte[] getMSISDN(); + + boolean isGMLCNumberAVPPresent(); + byte[] getGMLCNumber(); + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/ClientSLgSessionDataLocalImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/ClientSLgSessionDataLocalImpl.java new file mode 100644 index 000000000..48fb95984 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/ClientSLgSessionDataLocalImpl.java @@ -0,0 +1,57 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slg; + +import org.jdiameter.common.impl.app.slg.SLgLocalSessionDataImpl; + +/** + * @author Fernando Mendioroz + * + */ + +public class ClientSLgSessionDataLocalImpl extends SLgLocalSessionDataImpl implements IClientSLgSessionData { + + public ClientSLgSessionDataLocalImpl() { + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/Event.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/Event.java new file mode 100644 index 000000000..cf7aa30c8 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/Event.java @@ -0,0 +1,107 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slg; + +import org.jdiameter.api.InternalException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateEvent; + +/** + * @author Fernando Mendioroz + * + */ + +public class Event implements StateEvent { + + enum Type { + SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_PLA, RECEIVE_LRA; + } + + AppEvent request; + AppEvent answer; + Type type; + + Event(Type type, AppEvent request, AppEvent answer) { + this.type = type; + this.answer = answer; + this.request = request; + } + + @SuppressWarnings("unchecked") + public E encodeType(Class eClass) { + return eClass == Type.class ? (E) type : null; + } + + @SuppressWarnings("rawtypes") + public Enum getType() { + return type; + } + + public AppEvent getRequest() { + return request; + } + + public AppEvent getAnswer() { + return answer; + } + + public int compareTo(Object o) { + return 0; + } + + public Object getData() { + return request != null ? request : answer; + } + + public void setData(Object data) { + try { + if (((AppEvent) data).getMessage().isRequest()) { + request = (AppEvent) data; + } else { + answer = (AppEvent) data; + } + } catch (InternalException e) { + throw new IllegalArgumentException(e); + } + } +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/IClientSLgSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/IClientSLgSessionData.java new file mode 100644 index 000000000..bf25296ca --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/IClientSLgSessionData.java @@ -0,0 +1,54 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slg; + +import org.jdiameter.common.api.app.slg.ISLgSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public interface IClientSLgSessionData extends ISLgSessionData { + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/SLgClientSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/SLgClientSessionImpl.java new file mode 100644 index 000000000..4369e2e2f --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slg/SLgClientSessionImpl.java @@ -0,0 +1,358 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slg; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.EventListener; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.app.StateEvent; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ClientSLgSessionListener; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.client.impl.app.slg.Event.Type; +import org.jdiameter.common.api.app.slg.ISLgMessageFactory; +import org.jdiameter.common.api.app.slg.SLgSessionState; +import org.jdiameter.common.impl.app.AppAnswerEventImpl; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.jdiameter.common.impl.app.slg.SLgSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLgClientSessionImpl extends SLgSession + implements ClientSLgSession, EventListener, NetworkReqListener { + + private static final Logger logger = LoggerFactory.getLogger(SLgClientSessionImpl.class); + + private transient ClientSLgSessionListener listener; + + protected long appId = -1; + protected IClientSLgSessionData sessionData; + + public SLgClientSessionImpl(IClientSLgSessionData sessionData, ISLgMessageFactory fct, ISessionFactory sf, + ClientSLgSessionListener lst) { + super(sf, sessionData); + if (lst == null) { + throw new IllegalArgumentException("Listener can not be null"); + } + if (fct.getApplicationId() < 0) { + throw new IllegalArgumentException("ApplicationId can not be less than zero"); + } + + this.appId = fct.getApplicationId(); + this.listener = lst; + super.messageFactory = fct; + this.sessionData = sessionData; + } + + @SuppressWarnings("unchecked") + public E getState(Class stateType) { + return stateType == SLgSessionState.class ? (E) this.sessionData.getSLgSessionState() : null; + } + + public Answer processRequest(Request request) { + RequestDelivery rd = new RequestDelivery(); + rd.session = this; + rd.request = request; + super.scheduler.execute(rd); + return null; + } + + public void sendProvideLocationRequest(ProvideLocationRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + send(Event.Type.SEND_MESSAGE, request, null); + } + + public void sendLocationReportRequest(LocationReportRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + send(Event.Type.SEND_MESSAGE, request, null); + } + + public void receivedSuccessMessage(Request request, Answer answer) { + AnswerDelivery rd = new AnswerDelivery(); + rd.session = this; + rd.request = request; + rd.answer = answer; + super.scheduler.execute(rd); + } + + public void timeoutExpired(Request request) { + try { + handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); + } catch (Exception e) { + logger.debug("Failed to process timeout message", e); + } + } + + protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { + try { + if (type != null) { + handleEvent(new Event(type, request, answer)); + } + } catch (Exception e) { + throw new InternalException(e); + } + } + + public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { + try { + sendAndStateLock.lock(); + if (!super.session.isValid()) { + // FIXME: throw new InternalException("Generic session is not valid."); + return false; + } + final SLgSessionState state = this.sessionData.getSLgSessionState(); + SLgSessionState newState = null; + Event localEvent = (Event) event; + Event.Type eventType = (Type) event.getType(); + switch (state) { + + case IDLE: + switch (eventType) { + + case SEND_MESSAGE: + newState = SLgSessionState.MESSAGE_SENT_RECEIVED; + super.session.send(((AppEvent) event.getData()).getMessage(), this); + setState(newState); // FIXME: is this ok to be here? + break; + + default: + logger.error("Invalid Event Type {} for SLg Client Session at state {}.", eventType, + sessionData.getSLgSessionState()); + break; + } + break; + + case MESSAGE_SENT_RECEIVED: + switch (eventType) { + case TIMEOUT_EXPIRES: + newState = SLgSessionState.TIMEDOUT; + setState(newState); + break; + + case SEND_MESSAGE: + try { + super.session.send(((AppEvent) event.getData()).getMessage(), this); + } finally { + newState = SLgSessionState.TERMINATED; + setState(newState); + } + break; + + case RECEIVE_PLA: + newState = SLgSessionState.TERMINATED; + setState(newState); + super.cancelMsgTimer(); + listener.doProvideLocationAnswerEvent(this, (ProvideLocationRequest) localEvent.getRequest(), + (ProvideLocationAnswer) localEvent.getAnswer()); + break; + + case RECEIVE_LRA: + newState = SLgSessionState.TERMINATED; + setState(newState); + super.cancelMsgTimer(); + listener.doLocationReportAnswerEvent(this, (LocationReportRequest) localEvent.getRequest(), + (LocationReportAnswer) localEvent.getAnswer()); + break; + + default: + throw new InternalException("Unexpected/Unknown message received: " + event.getData()); + } + break; + + case TERMINATED: + throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); + + case TIMEDOUT: + throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); + + default: + logger.error("SLg Client FSM in wrong state: {}", state); + break; + } + } catch (Exception e) { + throw new InternalException(e); + } finally { + sendAndStateLock.unlock(); + } + return true; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void setState(SLgSessionState newState) { + SLgSessionState oldState = this.sessionData.getSLgSessionState(); + this.sessionData.setSLgSessionState(newState); + + for (StateChangeListener i : stateListeners) { + i.stateChanged(this, (Enum) oldState, (Enum) newState); + } + if (newState == SLgSessionState.TERMINATED || newState == SLgSessionState.TIMEDOUT) { + super.cancelMsgTimer(); + this.release(); + } + } + + public void onTimer(String timerName) { + if (timerName.equals(SLgSession.TIMER_NAME_MSG_TIMEOUT)) { + try { + sendAndStateLock.lock(); + try { + handleEvent( + new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); + } catch (Exception e) { + logger.debug("Failure handling Timeout event."); + } + this.sessionData.setBuffer(null); + this.sessionData.setTsTimerId(null); + } finally { + sendAndStateLock.unlock(); + } + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (int) (appId ^ (appId >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + + SLgClientSessionImpl other = (SLgClientSessionImpl) obj; + if (appId != other.appId) { + return false; + } + return true; + } + + @Override + public void release() { + if (isValid()) { + try { + sendAndStateLock.lock(); + super.release(); + } catch (Exception e) { + logger.debug("Failed to release session", e); + } finally { + sendAndStateLock.unlock(); + } + } else { + logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); + } + } + + private class RequestDelivery implements Runnable { + ClientSLgSession session; + Request request; + + public void run() { + try { + switch (request.getCommandCode()) { + + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), null); + break; + } + } catch (Exception e) { + logger.debug("Failed to process request message", e); + } + } + } + + private class AnswerDelivery implements Runnable { + ClientSLgSession session; + Answer answer; + Request request; + + public void run() { + try { + switch (answer.getCommandCode()) { + + case ProvideLocationAnswer.code: + handleEvent(new Event(Event.Type.RECEIVE_PLA, messageFactory.createProvideLocationRequest(request), + messageFactory.createProvideLocationAnswer(answer))); + break; + + case LocationReportAnswer.code: + handleEvent(new Event(Event.Type.RECEIVE_LRA, messageFactory.createLocationReportRequest(request), + messageFactory.createLocationReportAnswer(answer))); + break; + + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); + break; + } + } catch (Exception e) { + logger.debug("Failed to process success message", e); + } + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/ClientSLhSessionDataLocalImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/ClientSLhSessionDataLocalImpl.java new file mode 100644 index 000000000..35574cf27 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/ClientSLhSessionDataLocalImpl.java @@ -0,0 +1,57 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slh; + +import org.jdiameter.common.impl.app.slh.SLhLocalSessionDataImpl; + +/** + * @author Fernando Mendioroz + * + */ + +public class ClientSLhSessionDataLocalImpl extends SLhLocalSessionDataImpl implements IClientSLhSessionData { + + public ClientSLhSessionDataLocalImpl() { + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/Event.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/Event.java new file mode 100644 index 000000000..0c319912f --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/Event.java @@ -0,0 +1,107 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slh; + +import org.jdiameter.api.InternalException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateEvent; + +/** + * @author Fernando Mendioroz + * + */ +public class Event implements StateEvent { + + enum Type { + SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_RIA; + } + + AppEvent request; + AppEvent answer; + Type type; + + Event(Type type, AppEvent request, AppEvent answer) { + this.type = type; + this.answer = answer; + this.request = request; + } + + @SuppressWarnings("unchecked") + public E encodeType(Class eClass) { + return eClass == Type.class ? (E) type : null; + } + + @SuppressWarnings("rawtypes") + public Enum getType() { + return type; + } + + public AppEvent getRequest() { + return request; + } + + public AppEvent getAnswer() { + return answer; + } + + public int compareTo(Object o) { + return 0; + } + + public Object getData() { + return request != null ? request : answer; + } + + public void setData(Object data) { + try { + if (((AppEvent) data).getMessage().isRequest()) { + request = (AppEvent) data; + } else { + answer = (AppEvent) data; + } + } catch (InternalException e) { + throw new IllegalArgumentException(e); + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/IClientSLhSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/IClientSLhSessionData.java new file mode 100644 index 000000000..ccec9ab3c --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/IClientSLhSessionData.java @@ -0,0 +1,54 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slh; + +import org.jdiameter.common.api.app.slh.ISLhSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public interface IClientSLhSessionData extends ISLhSessionData { + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/SLhClientSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/SLhClientSessionImpl.java new file mode 100644 index 000000000..3fe11c2ec --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/client/impl/app/slh/SLhClientSessionImpl.java @@ -0,0 +1,336 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.client.impl.app.slh; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.EventListener; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.app.StateEvent; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ClientSLhSessionListener; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.client.impl.app.slh.Event.Type; +import org.jdiameter.common.api.app.slh.ISLhMessageFactory; +import org.jdiameter.common.api.app.slh.SLhSessionState; +import org.jdiameter.common.impl.app.AppAnswerEventImpl; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.jdiameter.common.impl.app.slh.SLhSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ +public class SLhClientSessionImpl extends SLhSession + implements ClientSLhSession, EventListener, NetworkReqListener { + + private static final Logger logger = LoggerFactory.getLogger(SLhClientSessionImpl.class); + + private transient ClientSLhSessionListener listener; + + protected long appId = -1; + protected IClientSLhSessionData sessionData; + + public SLhClientSessionImpl(IClientSLhSessionData sessionData, ISLhMessageFactory fct, ISessionFactory sf, ClientSLhSessionListener lst) { + super(sf, sessionData); + if (lst == null) { + throw new IllegalArgumentException("Listener can not be null"); + } + if (fct.getApplicationId() < 0) { + throw new IllegalArgumentException("ApplicationId can not be less than zero"); + } + + this.appId = fct.getApplicationId(); + this.listener = lst; + super.messageFactory = fct; + this.sessionData = sessionData; + } + + @SuppressWarnings("unchecked") + public E getState(Class stateType) { + return stateType == SLhSessionState.class ? (E) this.sessionData.getSLhSessionState() : null; + } + + public Answer processRequest(Request request) { + RequestDelivery rd = new RequestDelivery(); + rd.session = this; + rd.request = request; + super.scheduler.execute(rd); + return null; + } + + public void sendLCSRoutingInfoRequest(LCSRoutingInfoRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + send(Event.Type.SEND_MESSAGE, request, null); + } + + public void receivedSuccessMessage(Request request, Answer answer) { + AnswerDelivery rd = new AnswerDelivery(); + rd.session = this; + rd.request = request; + rd.answer = answer; + super.scheduler.execute(rd); + } + + public void timeoutExpired(Request request) { + try { + handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); + } catch (Exception e) { + logger.debug("Failed to process timeout message", e); + } + } + + protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { + try { + if (type != null) { + handleEvent(new Event(type, request, answer)); + } + } catch (Exception e) { + throw new InternalException(e); + } + } + + public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { + try { + sendAndStateLock.lock(); + if (!super.session.isValid()) { + // FIXME: throw new InternalException("Generic session is not valid."); + return false; + } + final SLhSessionState state = this.sessionData.getSLhSessionState(); + SLhSessionState newState = null; + Event localEvent = (Event) event; + Event.Type eventType = (Type) event.getType(); + switch (state) { + + case IDLE: + switch (eventType) { + + case SEND_MESSAGE: + newState = SLhSessionState.MESSAGE_SENT_RECEIVED; + super.session.send(((AppEvent) event.getData()).getMessage(), this); + setState(newState); // FIXME: is this ok to be here? + break; + + default: + logger.error("Invalid Event Type {} for SLh Client Session at state {}.", eventType, + sessionData.getSLhSessionState()); + break; + } + break; + + case MESSAGE_SENT_RECEIVED: + switch (eventType) { + case TIMEOUT_EXPIRES: + newState = SLhSessionState.TIMEDOUT; + setState(newState); + break; + + case SEND_MESSAGE: + try { + super.session.send(((AppEvent) event.getData()).getMessage(), this); + } finally { + newState = SLhSessionState.TERMINATED; + setState(newState); + } + break; + + case RECEIVE_RIA: + newState = SLhSessionState.TERMINATED; + setState(newState); + super.cancelMsgTimer(); + listener.doLCSRoutingInfoAnswerEvent(this, (LCSRoutingInfoRequest) localEvent.getRequest(), + (LCSRoutingInfoAnswer) localEvent.getAnswer()); + break; + + default: + throw new InternalException("Unexpected/Unknown message received: " + event.getData()); + } + break; + + case TERMINATED: + throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); + + case TIMEDOUT: + throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); + + default: + logger.error("SLh Client FSM in wrong state: {}", state); + break; + } + } catch (Exception e) { + throw new InternalException(e); + } finally { + sendAndStateLock.unlock(); + } + return true; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void setState(SLhSessionState newState) { + SLhSessionState oldState = this.sessionData.getSLhSessionState(); + this.sessionData.setSLhSessionState(newState); + + for (StateChangeListener i : stateListeners) { + i.stateChanged(this, (Enum) oldState, (Enum) newState); + } + if (newState == SLhSessionState.TERMINATED || newState == SLhSessionState.TIMEDOUT) { + super.cancelMsgTimer(); + this.release(); + } + } + + public void onTimer(String timerName) { + if (timerName.equals(SLhSession.TIMER_NAME_MSG_TIMEOUT)) { + try { + sendAndStateLock.lock(); + try { + handleEvent( + new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); + } catch (Exception e) { + logger.debug("Failure handling Timeout event."); + } + this.sessionData.setBuffer(null); + this.sessionData.setTsTimerId(null); + } finally { + sendAndStateLock.unlock(); + } + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (int) (appId ^ (appId >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + + SLhClientSessionImpl other = (SLhClientSessionImpl) obj; + if (appId != other.appId) { + return false; + } + return true; + } + + @Override + public void release() { + if (isValid()) { + try { + sendAndStateLock.lock(); + super.release(); + } catch (Exception e) { + logger.debug("Failed to release session", e); + } finally { + sendAndStateLock.unlock(); + } + } else { + logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); + } + } + + private class RequestDelivery implements Runnable { + ClientSLhSession session; + Request request; + + public void run() { + try { + switch (request.getCommandCode()) { + + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), null); + break; + } + } catch (Exception e) { + logger.debug("Failed to process request message", e); + } + } + } + + private class AnswerDelivery implements Runnable { + ClientSLhSession session; + Answer answer; + Request request; + + public void run() { + try { + switch (answer.getCommandCode()) { + + case LCSRoutingInfoAnswer.code: + handleEvent(new Event(Event.Type.RECEIVE_RIA, messageFactory.createLCSRoutingInfoRequest(request), + messageFactory.createLCSRoutingInfoAnswer(answer))); + break; + + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); + break; + } + } catch (Exception e) { + logger.debug("Failed to process success message", e); + } + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgMessageFactory.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgMessageFactory.java new file mode 100644 index 000000000..53fc7cac3 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgMessageFactory.java @@ -0,0 +1,74 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slg; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.Request; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.api.slg.events.ProvideLocationRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ISLgMessageFactory { + + ProvideLocationRequest createProvideLocationRequest(Request request); + + ProvideLocationAnswer createProvideLocationAnswer(Answer answer); + + LocationReportRequest createLocationReportRequest(Request request); + + LocationReportAnswer createLocationReportAnswer(Answer answer); + + /** + * Returns the Application-Id that this message factory is related to + * + * @return the Application-Id value + */ + long getApplicationId(); + +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionData.java new file mode 100644 index 000000000..39644e95a --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionData.java @@ -0,0 +1,68 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slg; + +import java.io.Serializable; + +import org.jdiameter.api.Request; +import org.jdiameter.common.api.app.IAppSessionData; + +/** + * @author Fernando Mendioroz + * + */ +public interface ISLgSessionData extends IAppSessionData { + + void setSLgSessionState(SLgSessionState state); + + SLgSessionState getSLgSessionState(); + + Serializable getTsTimerId(); + + void setTsTimerId(Serializable tid); + + void setBuffer(Request buffer); + + Request getBuffer(); + +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionFactory.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionFactory.java new file mode 100644 index 000000000..6dc72e34b --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/ISLgSessionFactory.java @@ -0,0 +1,111 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slg; + +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.slg.ClientSLgSessionListener; +import org.jdiameter.api.slg.ServerSLgSessionListener; +import org.jdiameter.common.api.app.IAppSessionFactory; +// import org.jdiameter.common.api.app.slg.ISLgMessageFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ISLgSessionFactory extends IAppSessionFactory { + + /** + * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app session. + * However clustered session use this value when recreated! + * + * @return the serverSessionListener + */ + ServerSLgSessionListener getServerSessionListener(); + + /** + * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app session. + * However clustered session use this value when recreated! + * + * @param serverSessionListener the serverSessionListener to set + */ + void setServerSessionListener(ServerSLgSessionListener serverSessionListener); + + /** + * Get stack wide listener for sessions. In local mode it has similar effect as setting this directly in app session. + * However clustered session use this value when recreated! + * + * @return the clientSessionListener + */ + ClientSLgSessionListener getClientSessionListener(); + + /** + * Set stack wide listener for sessions. In local mode it has similar effect as setting this directly in app session. + * However clustered session use this value when recreated! + * + * @param clientSessionListener the clientSessionListener to set + */ + void setClientSessionListener(ClientSLgSessionListener clientSessionListener); + + /** + * @return the messageFactory + */ + ISLgMessageFactory getMessageFactory(); + + /** + * @param messageFactory the messageFactory to set + */ + void setMessageFactory(ISLgMessageFactory messageFactory); + + /** + * @return the stateListener + */ + StateChangeListener getStateListener(); + + /** + * @param stateListener the stateListener to set + */ + void setStateListener(StateChangeListener stateListener); + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/SLgSessionState.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/SLgSessionState.java new file mode 100644 index 000000000..8b6512641 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slg/SLgSessionState.java @@ -0,0 +1,54 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slg; + +/** + * @author Fernando Mendioroz + * + */ + +public enum SLgSessionState { + + IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; + +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhMessageFactory.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhMessageFactory.java new file mode 100644 index 000000000..a637b15ca --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhMessageFactory.java @@ -0,0 +1,68 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slh; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.Request; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ISLhMessageFactory { + + LCSRoutingInfoRequest createLCSRoutingInfoRequest(Request request); + + LCSRoutingInfoAnswer createLCSRoutingInfoAnswer(Answer answer); + + /** + * Returns the Application-Id that this message factory is related to + * + * @return the Application-Id value + */ + long getApplicationId(); + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionData.java new file mode 100644 index 000000000..49e22dfa4 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionData.java @@ -0,0 +1,69 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slh; + +import java.io.Serializable; + +import org.jdiameter.api.Request; +import org.jdiameter.common.api.app.IAppSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ISLhSessionData extends IAppSessionData { + + void setSLhSessionState(SLhSessionState state); + + SLhSessionState getSLhSessionState(); + + Serializable getTsTimerId(); + + void setTsTimerId(Serializable tid); + + void setBuffer(Request buffer); + + Request getBuffer(); + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionFactory.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionFactory.java new file mode 100644 index 000000000..cc0e1341a --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/ISLhSessionFactory.java @@ -0,0 +1,111 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slh; + +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.slh.ClientSLhSessionListener; +import org.jdiameter.api.slh.ServerSLhSessionListener; +import org.jdiameter.common.api.app.IAppSessionFactory; +// import org.jdiameter.common.api.app.slh.ISLhMessageFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public interface ISLhSessionFactory extends IAppSessionFactory { + + /** + * Get stack wide listener for sessions. In local mode it has similar effect + * as setting this directly in app session. However clustered session use this value when recreated! + * + * @return the serverSessionListener + */ + ServerSLhSessionListener getServerSessionListener(); + + /** + * Set stack wide listener for sessions. In local mode it has similar effect + * as setting this directly in app session. However clustered session use this value when recreated! + * + * @param serverSessionListener the serverSessionListener to set + */ + void setServerSessionListener(ServerSLhSessionListener serverSessionListener); + + /** + * Get stack wide listener for sessions. In local mode it has similar effect + * as setting this directly in app session. However clustered session use this value when recreated! + * + * @return the clientSessionListener + */ + ClientSLhSessionListener getClientSessionListener(); + + /** + * Set stack wide listener for sessions. In local mode it has similar effect + * as setting this directly in app session. However clustered session use this value when recreated! + * + * @param clientSessionListener the clientSessionListener to set + */ + void setClientSessionListener(ClientSLhSessionListener clientSessionListener); + + /** + * @return the messageFactory + */ + ISLhMessageFactory getMessageFactory(); + + /** + * @param messageFactory the messageFactory to set + */ + void setMessageFactory(ISLhMessageFactory messageFactory); + + /** + * @return the stateListener + */ + StateChangeListener getStateListener(); + + /** + * @param stateListener the stateListener to set + */ + void setStateListener(StateChangeListener stateListener); + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/SLhSessionState.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/SLhSessionState.java new file mode 100644 index 000000000..77b03afbb --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/api/app/slh/SLhSessionState.java @@ -0,0 +1,54 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.api.app.slh; + +/** + * @author Fernando Mendioroz + * + */ + +public enum SLhSessionState { + + IDLE, MESSAGE_SENT_RECEIVED, TERMINATED, TIMEDOUT; + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportAnswerImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportAnswerImpl.java new file mode 100644 index 000000000..0b65df013 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportAnswerImpl.java @@ -0,0 +1,245 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import org.jdiameter.api.Avp; +import org.jdiameter.api.Answer; +import org.jdiameter.api.Request; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class LocationReportAnswerImpl extends AppRequestEventImpl implements LocationReportAnswer { + + private static final long serialVersionUID = 1L; + + protected static final Logger logger = LoggerFactory.getLogger(LocationReportAnswerImpl.class); + + /** + * + * @param answer + */ + public LocationReportAnswerImpl(Answer answer) { + super(answer); + } + + /** + * + * @param request + * @param resultCode + */ + public LocationReportAnswerImpl(Request request, long resultCode) { + super(request.createAnswer(resultCode)); + } + + public Avp getResultCodeAvp() throws AvpDataException { + return null; + } + + @Override + public boolean isGMLCAddressAvpPresent() { + return super.message.getAvps().getAvp(Avp.GMLC_ADDRESS) != null; + } + + @Override + public java.net.InetAddress getGMLCAddress() { + Avp lcsGMLCAddressAvp = super.message.getAvps().getAvp(Avp.GMLC_ADDRESS); + if (lcsGMLCAddressAvp != null) { + try { + return lcsGMLCAddressAvp.getAddress(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isLRAFlagsAvpPresent() { + return super.message.getAvps().getAvp(Avp.LRA_FLAGS) != null; + } + + @Override + public long getLRAFLags() { + Avp lcsLRAFlagsAvp = super.message.getAvps().getAvp(Avp.LRA_FLAGS); + if (lcsLRAFlagsAvp != null) { + try { + return lcsLRAFlagsAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS LRA Flags AVP value", e); + } + } + return -1; + } + + @Override + public boolean isReportingPLMNListAvpPresent() { + return super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST) != null; + } + + @Override + public boolean isPrioritizedListIndicatorAvpPresent() { + Avp lcsReportingPLMNListAvp = super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST); + if (lcsReportingPLMNListAvp != null) { + try { + return lcsReportingPLMNListAvp.getGrouped().getAvp(Avp.PRIORITIZED_LIST_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Prioritized-List-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getPrioritizedListIndicator() { + Avp lcsReportingPLMNListAvp = super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST); + if (lcsReportingPLMNListAvp != null) { + try { + Avp lcsPrioritizedListIndicatorAvp = lcsReportingPLMNListAvp.getGrouped().getAvp(Avp.PRIORITIZED_LIST_INDICATOR); + if (lcsPrioritizedListIndicatorAvp != null){ + return lcsPrioritizedListIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GERAN-Positioning-Data AVP value", e); + } + } + return -1; + } + + @Override + public boolean isPLMNIDListAvpPresent() { + Avp lcsReportingPLMNListAvp = super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST); + if (lcsReportingPLMNListAvp != null) { + try { + return lcsReportingPLMNListAvp.getGrouped().getAvp(Avp.PLMN_ID_LIST) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain PLMN-Id-List AVP", e); + } + } + return false; + } + + @Override + public boolean isVisitedPLMNIdAvpPresent() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + return lcsPLMNIdListAvp.getGrouped().getAvp(Avp.VISITED_PLMN_ID) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Visited-PLMN-Id AVP", e); + } + } + return false; + } + + @Override + public byte[] getVisitedPLMNId() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + Avp lcsVisitedPLMNIdAvp = lcsPLMNIdListAvp.getGrouped().getAvp(Avp.VISITED_PLMN_ID); + if (lcsVisitedPLMNIdAvp != null){ + return lcsVisitedPLMNIdAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Visited PLMN ID AVP value", e); + } + } + return null; + } + + @Override + public boolean isPeriodicLocationSupportIndicatorAvpPresent() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + return lcsPLMNIdListAvp.getGrouped().getAvp(Avp.PERIODIC_LOCATION_SUPPORT_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Periodic-Location-Support-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getPeriodicLocationSupportIndicator() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + Avp lcsPeriodicLocationSupportIndicatorAvp = lcsPLMNIdListAvp.getGrouped().getAvp(Avp.PERIODIC_LOCATION_SUPPORT_INDICATOR); + if (lcsPeriodicLocationSupportIndicatorAvp != null){ + return lcsPeriodicLocationSupportIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Periodic Location Support Indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSReferenceNumberAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_REFERENCE_NUMBER) != null; + } + + @Override + public byte[] getLCSReferenceNumber() { + Avp lcsLCSReferenceNumberAvp = super.message.getAvps().getAvp(Avp.LCS_REFERENCE_NUMBER); + if (lcsLCSReferenceNumberAvp != null) { + try { + return lcsLCSReferenceNumberAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reference Number AVP value", e); + } + } + return null; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportRequestImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportRequestImpl.java new file mode 100644 index 000000000..eb0982d8d --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/LocationReportRequestImpl.java @@ -0,0 +1,1176 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.Message; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ +public class LocationReportRequestImpl extends AppRequestEventImpl implements LocationReportRequest { + + private static final long serialVersionUID = 1L; + + protected static final Logger logger = LoggerFactory.getLogger(LocationReportRequestImpl.class); + + public LocationReportRequestImpl(Message message) { + super(message); + message.setRequest(true); + } + + @Override + public boolean isLocationEventAvpPresent() { + return super.message.getAvps().getAvp(Avp.LOCATION_EVENT) != null; + } + + @Override + public int getLocationEvent() { + Avp slgLocationEventAvp = super.message.getAvps().getAvp(Avp.LOCATION_EVENT); + if (slgLocationEventAvp != null) { + try { + return slgLocationEventAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Location-Event AVP value", e); + } + } + return -1; + } + + @Override + public boolean isUserNameAvpPresent() { + return super.message.getAvps().getAvp(Avp.USER_NAME) != null; // IE: IMSI + } + + @Override + public String getUserName() { + Avp userNameAvp = super.message.getAvps().getAvp(Avp.USER_NAME); + if (userNameAvp != null) { + try { + return userNameAvp.getUTF8String(); // IE: IMSI mapped to User-Name + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain User-Name AVP value (IMSI)", e); + } + } + return null; + } + + @Override + public boolean isMSISDNAvpPresent() { + return super.message.getAvps().getAvp(Avp.MSISDN) != null; + } + + @Override + public byte[] getMSISDN() { + Avp msisdnAvp = super.message.getAvps().getAvp(Avp.MSISDN); + if (msisdnAvp != null) { + try { + return msisdnAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSISDN AVP value", e); + } + } + return null; + } + + @Override + public boolean isIMEIAvpPresent() { + return super.message.getAvps().getAvp(Avp.TGPP_IMEI) != null; + } + + @Override + public String getIMEI() { + Avp imeiAvp = super.message.getAvps().getAvp(Avp.TGPP_IMEI); + if (imeiAvp != null) { + try { + return imeiAvp.getUTF8String(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain IMEI AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSEPSClientNameAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME) != null; + } + + @Override + public boolean isLSCNameStringAvpPresent() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + return lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_NAME_STRING) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Name-String AVP", e); + } + } + return false; + } + + @Override + public String getLSCNameString() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + Avp lcsNameStringAvp = lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_NAME_STRING); + if (lcsNameStringAvp != null){ + return lcsNameStringAvp.getUTF8String(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Name-String AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSFormatIndicatorAvpPresent() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + return lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_FORMAT_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Format-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getLCSFormatIndicator() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + Avp lcsFormatIndicatorAvp = lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_FORMAT_INDICATOR); + if (lcsFormatIndicatorAvp != null){ + return lcsFormatIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Format-Indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLocationEstimateAvpPresent() { + return super.message.getAvps().getAvp(Avp.LOCATION_ESTIMATE) != null; + } + + @Override + public byte[] getLocationEstimate() { + Avp lcsLocationEstimateAvp = super.message.getAvps().getAvp(Avp.LOCATION_ESTIMATE); + if (lcsLocationEstimateAvp != null) { + try { + return lcsLocationEstimateAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Location-Estimate AVP value", e); + } + } + return null; + } + + @Override + public boolean isAccuracyFulfilmentIndicatorAvpPresent() { + return super.message.getAvps().getAvp(Avp.ACCURACY_FULFILMENT_INDICATOR) != null; + } + + @Override + public int getAccuracyFulfilmentIndicator() { + Avp lcsAccuracyFulfilmentIndAvp = super.message.getAvps().getAvp(Avp.ACCURACY_FULFILMENT_INDICATOR); + if (lcsAccuracyFulfilmentIndAvp != null) { + try { + return lcsAccuracyFulfilmentIndAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Accuracy fulfilment indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isAgeOfLocationEstimateAvpPresent() { + return super.message.getAvps().getAvp(Avp.AGE_OF_LOCATION_ESTIMATE) != null; + } + + @Override + public long getAgeOfLocationEstimate() { + Avp lcsAgeOfLocEstimateAvp = super.message.getAvps().getAvp(Avp.AGE_OF_LOCATION_ESTIMATE); + if (lcsAgeOfLocEstimateAvp != null) { + try { + return lcsAgeOfLocEstimateAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Age of Location Estimate AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVelocityEstimateAvpPresent() { + return super.message.getAvps().getAvp(Avp.VELOCITY_ESTIMATE) != null; + } + + @Override + public byte[] getVelocityEstimate() { + Avp lcsVelEstimateAvp = super.message.getAvps().getAvp(Avp.VELOCITY_ESTIMATE); + if (lcsVelEstimateAvp != null) { + try { + return lcsVelEstimateAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Velocity Estimate AVP value", e); + } + } + return null; + } + + @Override + public boolean isEUTRANPositioningDataAvpPresent() { + return super.message.getAvps().getAvp(Avp.EUTRAN_POSITIONING_DATA) != null; + } + + @Override + public byte[] getEUTRANPositioningData() { + Avp lcsEUTRANPosDataAvp = super.message.getAvps().getAvp(Avp.EUTRAN_POSITIONING_DATA); + if (lcsEUTRANPosDataAvp != null) { + try { + return lcsEUTRANPosDataAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS E-UTRAN-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isECGIAvpPresent() { + return super.message.getAvps().getAvp(Avp.ECGI) != null; + } + + @Override + public byte[] getECGI() { + Avp lcsECGIAvp = super.message.getAvps().getAvp(Avp.ECGI); + if (lcsECGIAvp != null) { + try { + return lcsECGIAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS ECGI AVP value", e); + } + } + return null; + } + + @Override + public boolean isGERANPositioningInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO) != null; + } + + @Override + public boolean isGERANPositioningDataAvpPresent() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + return lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Reporting-Interval AVP", e); + } + } + return false; + } + + @Override + public byte[] getGERANPositioningData() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + Avp lcsGERANPositioningDataAvp = lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_POSITIONING_DATA); + if (lcsGERANPositioningDataAvp != null){ + return lcsGERANPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GERAN-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isGERANGANSSPositioningDataAvpPresent() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + return lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_GANSS_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GERAN-GANSS-Positioning-Data AVP", e); + } + } + return false; + } + + @Override + public byte[] getGERANGANSSPositioningData() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + Avp lcsGERANGANSSPositioningDataAvp = lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_GANSS_POSITIONING_DATA); + if (lcsGERANGANSSPositioningDataAvp != null){ + return lcsGERANGANSSPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GERAN-GANSS-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isCellGlobalIdentityAvpPresent() { + return super.message.getAvps().getAvp(Avp.CELL_GLOBAL_IDENTITY) != null; + } + + @Override + public byte[] getCellGlobalIdentity() { + Avp lcsCellGlobalIdAvp = super.message.getAvps().getAvp(Avp.CELL_GLOBAL_IDENTITY); + if (lcsCellGlobalIdAvp != null) { + try { + return lcsCellGlobalIdAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Cell-Global-Identity AVP value", e); + } + } + return null; + } + + @Override + public boolean isUTRANPositioningInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO) != null; + } + + @Override + public boolean isUTRANPositioningDataAvpPresent() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + return lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain UTRAN-Positioning-Data AVP", e); + } + } + return false; + } + + @Override + public byte[] getUTRANPositioningData() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + Avp lcsUTRANPositioningDataAvp = lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_POSITIONING_DATA); + if (lcsUTRANPositioningDataAvp != null){ + return lcsUTRANPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS UTRAN-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isUTRANGANSSPositioningDataAvpPresent() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + return lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_GANSS_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain UTRAN-GANSS-Positioning-Data AVP", e); + } + } + return false; + } + + @Override + public byte[] getUTRANGANSSPositioningData() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + Avp lcsUTRANGANSSPositioningDataAvp = lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_GANSS_POSITIONING_DATA); + if (lcsUTRANGANSSPositioningDataAvp != null){ + return lcsUTRANGANSSPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS UTRAN-GANSS-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isServiceAreaIdentityAvpPresent() { + return super.message.getAvps().getAvp(Avp.SERVICE_AREA_IDENTITY) != null; + } + + @Override + public byte[] getServiceAreaIdentity() { + Avp lcsServiceAreaIdentityAvp = super.message.getAvps().getAvp(Avp.SERVICE_AREA_IDENTITY); + if (lcsServiceAreaIdentityAvp != null) { + try { + return lcsServiceAreaIdentityAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SERVICE-AREA-IDENTITY AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSServiceTypeIDAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_SERVICE_TYPE_ID) != null; + } + + @Override + public long getLCSServiceTypeID() { + Avp lcsLCSServiceTypeIDAvp = super.message.getAvps().getAvp(Avp.LCS_SERVICE_TYPE_ID); + if (lcsLCSServiceTypeIDAvp != null) { + try { + return lcsLCSServiceTypeIDAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Service Type ID AVP value", e); + } + } + return -1; + } + + @Override + public boolean isPseudonymIndicatorAvpPresent() { + return super.message.getAvps().getAvp(Avp.PSEUDONYM_INDICATOR) != null; + } + + @Override + public int getPseudonymIndicator() { + Avp lcsPseudonymIndicatorAvp = super.message.getAvps().getAvp(Avp.PSEUDONYM_INDICATOR); + if (lcsPseudonymIndicatorAvp != null) { + try { + return lcsPseudonymIndicatorAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Pseudonym Indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSQoSAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_QOS) != null; + } + + @Override + public boolean isLCSQoSClassAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.LCS_QOS_CLASS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-QoS-Class AVP", e); + } + } + return false; + } + + @Override + public int getLCSQoSClass() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSClassAvp = lcsQoSAvp.getGrouped().getAvp(Avp.LCS_QOS_CLASS); + if (lcsQoSClassAvp != null){ + return lcsQoSClassAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-QoS-Class AVP value", e); + } + } + return -1; + } + + @Override + public boolean isHorizontalAccuracyAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.HORIZONTAL_ACCURACY) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Horizontal-Accuracy AVP", e); + } + } + return false; + } + + @Override + public long getHorizontalAccuracy() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSHorizontalAccuracyAvp = lcsQoSAvp.getGrouped().getAvp(Avp.HORIZONTAL_ACCURACY); + if (lcsQoSHorizontalAccuracyAvp != null){ + return lcsQoSHorizontalAccuracyAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Horizontal-Accuracy AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVerticalAccuracyAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_ACCURACY) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Accuracy AVP", e); + } + } + return false; + } + + @Override + public long getVerticalAccuracy() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSVerticalAccuracyAvp = lcsQoSAvp.getGrouped().getAvp(Avp.HORIZONTAL_ACCURACY); + if (lcsQoSVerticalAccuracyAvp != null){ + return lcsQoSVerticalAccuracyAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Accuracy AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVerticalRequestedAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_REQUESTED) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Requested AVP", e); + } + } + return false; + } + + public int getVerticalRequested() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSVerticalRequestedAvp = lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_REQUESTED); + if (lcsQoSVerticalRequestedAvp != null){ + return lcsQoSVerticalRequestedAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Requested AVP value", e); + } + } + return -1; + } + + @Override + public boolean isResponseTimeAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.RESPONSE_TIME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Response-Time AVP", e); + } + } + return false; + } + + @Override + public int getResponseTime() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSResponseTimeAvp = lcsQoSAvp.getGrouped().getAvp(Avp.RESPONSE_TIME); + if (lcsQoSResponseTimeAvp != null){ + return lcsQoSResponseTimeAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Response-Time AVP value", e); + } + } + return -1; + } + + @Override + public boolean isServingNodeAvpPresent() { + return super.message.getAvps().getAvp(Avp.SERVING_NODE) != null; + } + + @Override + public boolean isSGSNNumberAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getSGSNNumber() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsSGSNNumberAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER); + if (lcsSGSNNumberAvp != null){ + return lcsSGSNNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isSGSNNameAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Name AVP", e); + } + } + return false; + } + + @Override + public String getSGSNName() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsSGSNNameAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME); + if (lcsSGSNNameAvp != null){ + return lcsSGSNNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isSGSNRealmAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Realm AVP", e); + } + } + return false; + } + + @Override + public String getSGSNRealm() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsSGSNRealmAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM); + if (lcsSGSNRealmAvp != null){ + return lcsSGSNRealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isMMENameAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Name AVP", e); + } + } + return false; + } + + @Override + public String getMMEName() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsMMENameAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_NAME); + if (lcsMMENameAvp != null){ + return lcsMMENameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isMMERealmAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_REALM) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Realm AVP", e); + } + } + return false; + } + + @Override + public String getMMERealm() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsMMERealmAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_REALM); + if (lcsMMERealmAvp != null){ + return lcsMMERealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isMSCNumberAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MSC-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getMSCNumber() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsMSCNumberAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER); + if (lcsMSCNumberAvp != null){ + return lcsMSCNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MSC-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean is3GPPAAAServerNameAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS 3GPP-AAA-Server-Name AVP", e); + } + } + return false; + } + + @Override + public String get3GPPAAAServerName() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcs3GPPAAAServerNameAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME); + if (lcs3GPPAAAServerNameAvp != null){ + return lcs3GPPAAAServerNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS 3GPP-AAA-Server-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSCapabilitiesSetsAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets AVP", e); + } + } + return false; + } + + @Override + public long getLCSCapabilitiesSets() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsCapabilitiesSetsAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS); + if (lcsCapabilitiesSetsAvp != null){ + return lcsCapabilitiesSetsAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets AVP value", e); + } + } + return -1; + } + + @Override + public boolean isGMLCAddressAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GMLC-Address AVP", e); + } + } + return false; + } + + @Override + public java.net.InetAddress getGMLCAddress() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsCapabilitiesSetsAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS); + if (lcsCapabilitiesSetsAvp != null){ + return lcsCapabilitiesSetsAvp.getAddress(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GMLC-Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isLRRFlagsAvpPresent() { + return super.message.getAvps().getAvp(Avp.LRR_FLAGS) != null; + } + + @Override + public long getLRRFLags() { + Avp lcsLRRFlagsAvp = super.message.getAvps().getAvp(Avp.LRR_FLAGS); + if (lcsLRRFlagsAvp != null) { + try { + return lcsLRRFlagsAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS LRR Flags AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSReferenceNumberAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_REFERENCE_NUMBER) != null; + } + + @Override + public byte[] getLCSReferenceNumber() { + Avp lcsLCSReferenceNumberAvp = super.message.getAvps().getAvp(Avp.LCS_REFERENCE_NUMBER); + if (lcsLCSReferenceNumberAvp != null) { + try { + return lcsLCSReferenceNumberAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reference Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isDeferredMTLRDataAvpPresent() { + return super.message.getAvps().getAvp(Avp.DEFERRED_MT_LR_DATA) != null; + } + + @Override + public boolean isDeferredLocationTypeAvpPresent() { + Avp lcsDeferredMTLRDataAvp = super.message.getAvps().getAvp(Avp.DEFERRED_MT_LR_DATA); + if (lcsDeferredMTLRDataAvp != null) { + try { + return lcsDeferredMTLRDataAvp.getGrouped().getAvp(Avp.DEFERRED_LOCATION_TYPE) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Deferred-Location-Type AVP", e); + } + } + return false; + } + + @Override + public long getDeferredLocationType() { + Avp lcsDeferredMTLRDataAvp = super.message.getAvps().getAvp(Avp.DEFERRED_MT_LR_DATA); + if (lcsDeferredMTLRDataAvp != null) { + try { + Avp deferredLocationType = lcsDeferredMTLRDataAvp.getGrouped().getAvp(Avp.DEFERRED_LOCATION_TYPE); + if (deferredLocationType != null){ + return deferredLocationType.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Deferred Location Type AVP value", e); + } + } + return -1; + } + + @Override + public boolean isTerminationCauseAvpPresent() { + Avp lcsDeferredMTLRDataAvp = super.message.getAvps().getAvp(Avp.DEFERRED_MT_LR_DATA); + if (lcsDeferredMTLRDataAvp != null) { + try { + return lcsDeferredMTLRDataAvp.getGrouped().getAvp(Avp.TERMINATION_CAUSE_LCS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Termination-Cause AVP", e); + } + } + return false; + } + + @Override + public long getTerminationCause() { + Avp lcsDeferredMTLRDataAvp = super.message.getAvps().getAvp(Avp.DEFERRED_MT_LR_DATA); + if (lcsDeferredMTLRDataAvp != null) { + try { + Avp lcsTerminationCause = lcsDeferredMTLRDataAvp.getGrouped().getAvp(Avp.TERMINATION_CAUSE_LCS); + if (lcsTerminationCause != null){ + return lcsTerminationCause.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Termination-Cause AVP value", e); + } + } + return -1; + } + + @Override + public boolean isHGMLCAddressAvpPresent() { + return super.message.getAvps().getAvp(Avp.GMLC_ADDRESS) != null; // IE: H-GMLC Address mapped to GMLC-Address AVP + } + + @Override + public java.net.InetAddress getHGMLCAddress() { + Avp lcsHGMLCAddressAvp = super.message.getAvps().getAvp(Avp.GMLC_ADDRESS); // IE: H-GMLC Address mapped to GMLC-Address AVP + if (lcsHGMLCAddressAvp != null) { + try { + return lcsHGMLCAddressAvp.getAddress(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain H-GMLC-Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isPeriodicLDRInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION) != null; + } + + @Override + public boolean isReportingAmountAvpPresent() { + Avp lcsPeriodicLDRInfoAvp = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfoAvp != null) { + try { + return lcsPeriodicLDRInfoAvp.getGrouped().getAvp(Avp.REPORTING_AMOUNT) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reporting-Amount AVP", e); + } + } + return false; + } + + @Override + public long getReportingAmount() { + Avp lcsPeriodicLDRInfoAvp = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfoAvp != null) { + try { + Avp lcsReportingAmountAvp = lcsPeriodicLDRInfoAvp.getGrouped().getAvp(Avp.REPORTING_AMOUNT); + if (lcsReportingAmountAvp != null){ + return lcsReportingAmountAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reporting amount AVP value", e); + } + } + return -1; + } + + @Override + public boolean isReportingIntervalAvpPresent() { + Avp lcsPeriodicLDRInfo = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfo != null) { + try { + return lcsPeriodicLDRInfo.getGrouped().getAvp(Avp.REPORTING_INTERVAL) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Reporting-Interval AVP", e); + } + } + return false; + } + + @Override + public long getReportingInterval() { + Avp lcsPeriodicLDRInfo = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfo != null) { + try { + Avp lcsReportingIntervalAvp = lcsPeriodicLDRInfo.getGrouped().getAvp(Avp.REPORTING_INTERVAL); + if (lcsReportingIntervalAvp != null){ + return lcsReportingIntervalAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reporting-Interval AVP value", e); + } + } + return -1; + } + + @Override + public boolean isESMLCCellInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.ESMLC_CELL_INFO) != null; + } + + @Override + public long getCellPortionId() { + Avp lcsCellPortionIdAvp = super.message.getAvps().getAvp(Avp.CELL_PORTION_ID); + if (lcsCellPortionIdAvp != null) { + try { + return lcsCellPortionIdAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Cell-Portion-Id AVP value", e); + } + } + return -1; + } + + @Override + public boolean is1xRTTRCIDAvpPresent() { + return super.message.getAvps().getAvp(Avp.ONEXRTT_RCID) != null; + } + + @Override + public byte[] get1xRTTRCID() { + Avp lcs1xRTTRCIDAvp = super.message.getAvps().getAvp(Avp.ONEXRTT_RCID); + if (lcs1xRTTRCIDAvp != null) { + try { + return lcs1xRTTRCIDAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS 1xRTT_RCID AVP value", e); + } + } + return null; + } + + @Override + public boolean isCivicAddressAvpPresent() { + return super.message.getAvps().getAvp(Avp.CIVIC_ADDRESS) != null; + } + + @Override + public String getCivicAddress() { + Avp lcsCivicAddressAvp = super.message.getAvps().getAvp(Avp.CIVIC_ADDRESS); + if (lcsCivicAddressAvp != null) { + try { + return lcsCivicAddressAvp.getUTF8String(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Civic Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isBarometricPressureAvpPresent() { + return super.message.getAvps().getAvp(Avp.BAROMETRIC_PRESSURE) != null; + } + + @Override + public long getBarometricPressure() { + Avp lcsBarometricPressureAvp = super.message.getAvps().getAvp(Avp.BAROMETRIC_PRESSURE); + if (lcsBarometricPressureAvp != null) { + try { + return lcsBarometricPressureAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Barometric Pressure AVP value", e); + } + } + return -1; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationAnswerImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationAnswerImpl.java new file mode 100644 index 000000000..ae66d33f7 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationAnswerImpl.java @@ -0,0 +1,695 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import org.jdiameter.api.Avp; +import org.jdiameter.api.Answer; +import org.jdiameter.api.Request; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class ProvideLocationAnswerImpl extends AppRequestEventImpl implements ProvideLocationAnswer { + + private static final long serialVersionUID = 1L; + + protected static final Logger logger = LoggerFactory.getLogger(ProvideLocationRequestImpl.class); + + /** + * + * @param answer + */ + public ProvideLocationAnswerImpl(Answer answer) { + super(answer); + } + + /** + * + * @param request + * @param resultCode + */ + public ProvideLocationAnswerImpl(Request request, long resultCode) { + super(request.createAnswer(resultCode)); + } + + public Avp getResultCodeAvp() throws AvpDataException { + return null; + } + + @Override + public boolean isLocationEstimateAvpPresent() { + return super.message.getAvps().getAvp(Avp.LOCATION_ESTIMATE) != null; + } + + @Override + public byte[] getLocationEstimate() { + Avp lcsLocationEstimateAvp = super.message.getAvps().getAvp(Avp.LOCATION_ESTIMATE); + if (lcsLocationEstimateAvp != null) { + try { + return lcsLocationEstimateAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Location-Estimate AVP value", e); + } + } + return null; + } + + @Override + public boolean isAccuracyFulfilmentIndicatorAvpPresent() { + return super.message.getAvps().getAvp(Avp.ACCURACY_FULFILMENT_INDICATOR) != null; + } + + @Override + public int getAccuracyFulfilmentIndicator() { + Avp lcsAccuracyFulfilmentIndAvp = super.message.getAvps().getAvp(Avp.ACCURACY_FULFILMENT_INDICATOR); + if (lcsAccuracyFulfilmentIndAvp != null) { + try { + return lcsAccuracyFulfilmentIndAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Accuracy fulfilment indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isAgeOfLocationEstimateAvpPresent() { + return super.message.getAvps().getAvp(Avp.AGE_OF_LOCATION_ESTIMATE) != null; + } + + @Override + public long getAgeOfLocationEstimate() { + Avp lcsAgeOfLocEstimateAvp = super.message.getAvps().getAvp(Avp.AGE_OF_LOCATION_ESTIMATE); + if (lcsAgeOfLocEstimateAvp != null) { + try { + return lcsAgeOfLocEstimateAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Age of Location Estimate AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVelocityEstimateAvpPresent() { + return super.message.getAvps().getAvp(Avp.VELOCITY_ESTIMATE) != null; + } + + @Override + public byte[] getVelocityEstimate() { + Avp lcsVelEstimateAvp = super.message.getAvps().getAvp(Avp.VELOCITY_ESTIMATE); + if (lcsVelEstimateAvp != null) { + try { + return lcsVelEstimateAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Velocity Estimate AVP value", e); + } + } + return null; + } + + @Override + public boolean isEUTRANPositioningDataAvpPresent() { + return super.message.getAvps().getAvp(Avp.EUTRAN_POSITIONING_DATA) != null; + } + + @Override + public byte[] getEUTRANPositioningData() { + Avp lcsEUTRANPosDataAvp = super.message.getAvps().getAvp(Avp.EUTRAN_POSITIONING_DATA); + if (lcsEUTRANPosDataAvp != null) { + try { + return lcsEUTRANPosDataAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS E-UTRAN-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isECGIAvpPresent() { + return super.message.getAvps().getAvp(Avp.ECGI) != null; + } + + @Override + public byte[] getECGI(){ + Avp lcsECGIAvp = super.message.getAvps().getAvp(Avp.ECGI); + if (lcsECGIAvp != null) { + try { + return lcsECGIAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS ECGI AVP value", e); + } + } + return null; + } + + @Override + public boolean isGERANPositioningInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO) != null; + } + + @Override + public boolean isGERANPositioningDataAVPPresent(){ + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + return lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Reporting-Interval AVP", e); + } + } + return false; + } + + @Override + public byte[] getGERANPositioningData() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + Avp lcsGERANPositioningDataAvp = lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_POSITIONING_DATA); + if (lcsGERANPositioningDataAvp != null){ + return lcsGERANPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GERAN-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isGERANGANSSPositioningDataAVPPresent() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + return lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_GANSS_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GERAN-GANSS-Positioning-Data AVP", e); + } + } + return false; + } + + @Override + public byte[] getGERANGANSSPositioningData() { + Avp lcsGERANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.GERAN_POSITIONING_INFO); + if (lcsGERANPositioningInfoAvp != null) { + try { + Avp lcsGERANGANSSPositioningDataAvp = lcsGERANPositioningInfoAvp.getGrouped().getAvp(Avp.GERAN_GANSS_POSITIONING_DATA); + if (lcsGERANGANSSPositioningDataAvp != null){ + return lcsGERANGANSSPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GERAN-GANSS-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isCellGlobalIdentityAvpPresent() { + return super.message.getAvps().getAvp(Avp.CELL_GLOBAL_IDENTITY) != null; + } + + @Override + public byte[] getCellGlobalIdentity() { + Avp lcsCellGlobalIdAvp = super.message.getAvps().getAvp(Avp.CELL_GLOBAL_IDENTITY); + if (lcsCellGlobalIdAvp != null) { + try { + return lcsCellGlobalIdAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Cell-Global-Identity AVP value", e); + } + } + return null; + } + + @Override + public boolean isUTRANPositioningInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO) != null; + } + + @Override + public boolean isUTRANPositioningDataAVPPresent() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + return lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain UTRAN-Positioning-Data AVP", e); + } + } + return false; + } + + @Override + public byte[] getUTRANPositioningData() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + Avp lcsUTRANPositioningDataAvp = lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_POSITIONING_DATA); + if (lcsUTRANPositioningDataAvp != null){ + return lcsUTRANPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS UTRAN-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isUTRANGANSSPositioningDataAVPPresent() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + return lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_GANSS_POSITIONING_DATA) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain UTRAN-GANSS-Positioning-Data AVP", e); + } + } + return false; + } + + @Override + public byte[] getUTRANGANSSPositioningData() { + Avp lcsUTRANPositioningInfoAvp = super.message.getAvps().getAvp(Avp.UTRAN_POSITIONING_INFO); + if (lcsUTRANPositioningInfoAvp != null) { + try { + Avp lcsUTRANGANSSPositioningDataAvp = lcsUTRANPositioningInfoAvp.getGrouped().getAvp(Avp.UTRAN_GANSS_POSITIONING_DATA); + if (lcsUTRANGANSSPositioningDataAvp != null){ + return lcsUTRANGANSSPositioningDataAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS UTRAN-GANSS-Positioning-Data AVP value", e); + } + } + return null; + } + + @Override + public boolean isServiceAreaIdentityAvpPresent() { + return super.message.getAvps().getAvp(Avp.SERVICE_AREA_IDENTITY) != null; + } + + @Override + public byte[] getServiceAreaIdentity() { + Avp lcsServiceAreaIdentityAvp = super.message.getAvps().getAvp(Avp.SERVICE_AREA_IDENTITY); + if (lcsServiceAreaIdentityAvp != null) { + try { + return lcsServiceAreaIdentityAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SERVICE-AREA-IDENTITY AVP value", e); + } + } + return null; + } + + @Override + public boolean isServingNodeAvpPresent() { + return super.message.getAvps().getAvp(Avp.SERVING_NODE) != null; + } + + @Override + public boolean isSGSNNumberAvpPresent(){ + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getSGSNNumber() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsSGSNNumberAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER); + if (lcsSGSNNumberAvp != null){ + return lcsSGSNNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isSGSNNameAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Name AVP", e); + } + } + return false; + } + + @Override + public String getSGSNName() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsSGSNNameAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME); + if (lcsSGSNNameAvp != null){ + return lcsSGSNNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isSGSNRealmAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Realm AVP", e); + } + } + return false; + } + + @Override + public String getSGSNRealm() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsSGSNRealmAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM); + if (lcsSGSNRealmAvp != null){ + return lcsSGSNRealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS SGSN-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isMMENameAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Name AVP", e); + } + } + return false; + } + + @Override + public String getMMEName() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsMMENameAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_NAME); + if (lcsMMENameAvp != null){ + return lcsMMENameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isMMERealmAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_REALM) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Realm AVP", e); + } + } + return false; + } + + @Override + public String getMMERealm() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsMMERealmAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.MME_REALM); + if (lcsMMERealmAvp != null){ + return lcsMMERealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MME-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isMSCNumberAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MSC-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getMSCNumber() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsMSCNumberAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER); + if (lcsMSCNumberAvp != null){ + return lcsMSCNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS MSC-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean is3GPPAAAServerNameAvpPResent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS 3GPP-AAA-Server-Name AVP", e); + } + } + return false; + } + + @Override + public String get3GPPAAAServerName() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcs3GPPAAAServerNameAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME); + if (lcs3GPPAAAServerNameAvp != null){ + return lcs3GPPAAAServerNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS 3GPP-AAA-Server-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSCapabilitiesSetsAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets AVP", e); + } + } + return false; + } + + @Override + public long getLCSCapabilitiesSets() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsCapabilitiesSetsAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS); + if (lcsCapabilitiesSetsAvp != null){ + return lcsCapabilitiesSetsAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets AVP value", e); + } + } + return -1; + } + + @Override + public boolean isGMLCAddressAvpPresent() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + return lcsServingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GMLC-Address AVP", e); + } + } + return false; + } + + @Override + public java.net.InetAddress getGMLCAddress() { + Avp lcsServingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (lcsServingNodeAvp != null) { + try { + Avp lcsCapabilitiesSetsAvp = lcsServingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS); + if (lcsCapabilitiesSetsAvp != null){ + return lcsCapabilitiesSetsAvp.getAddress(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GMLC-Address AVP value", e); + } + } + return null; + } + + + @Override + public boolean isPLAFlagsAvpPresent() { + return super.message.getAvps().getAvp(Avp.PLA_FLAGS) != null; + } + + @Override + public long getPLAFlags(){ + Avp lcsPLAFlagsAvp = super.message.getAvps().getAvp(Avp.PLA_FLAGS); + if (lcsPLAFlagsAvp != null) { + try { + return lcsPLAFlagsAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS PLA-Flags AVP value", e); + } + } + return -1; + } + + @Override + public boolean isESMLCCellInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.ESMLC_CELL_INFO) != null; + } + + @Override + public long getCellPortionId() { + Avp lcsCellPortionIdAvp = super.message.getAvps().getAvp(Avp.CELL_PORTION_ID); + if (lcsCellPortionIdAvp != null) { + try { + return lcsCellPortionIdAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Cell-Portion-Id AVP value", e); + } + } + return -1; + } + + @Override + public boolean isCivicAddressAvpPresent() { + return super.message.getAvps().getAvp(Avp.CIVIC_ADDRESS) != null; + } + + @Override + public String getCivicAddress(){ + Avp lcsCivicAddressAvp = super.message.getAvps().getAvp(Avp.CIVIC_ADDRESS); + if (lcsCivicAddressAvp != null) { + try { + return lcsCivicAddressAvp.getUTF8String(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Civic Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isBarometricPressureAvpPresent() { + return super.message.getAvps().getAvp(Avp.BAROMETRIC_PRESSURE) != null; + } + + @Override + public long getBarometricPressure() { + Avp lcsBarometricPressureAvp = super.message.getAvps().getAvp(Avp.BAROMETRIC_PRESSURE); + if (lcsBarometricPressureAvp != null) { + try { + return lcsBarometricPressureAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Barometric Pressure AVP value", e); + } + } + return -1; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationRequestImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationRequestImpl.java new file mode 100644 index 000000000..4bf7cde32 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/ProvideLocationRequestImpl.java @@ -0,0 +1,983 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.Message; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ +public class ProvideLocationRequestImpl extends AppRequestEventImpl implements ProvideLocationRequest { + + private static final long serialVersionUID = 1L; + + protected static final Logger logger = LoggerFactory.getLogger(ProvideLocationRequestImpl.class); + + public ProvideLocationRequestImpl(Message message) { + super(message); + message.setRequest(true); + } + + @Override + public boolean isSLgLocationTypeAvpPresent() { + return super.message.getAvps().getAvp(Avp.SLG_LOCATION_TYPE) != null; + } + + @Override + public int getSLgLocationType() { + Avp slgLocationTypeAvp = super.message.getAvps().getAvp(Avp.SLG_LOCATION_TYPE); + if (slgLocationTypeAvp != null) { + try { + return slgLocationTypeAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SLg-Location-Type AVP value", e); + } + } + return -1; + } + + @Override + public boolean isUserNameAvpPresent() { + return super.message.getAvps().getAvp(Avp.USER_NAME) != null; // IE: IMSI + } + + @Override + public String getUserName() { + Avp userNameAvp = super.message.getAvps().getAvp(Avp.USER_NAME); + if (userNameAvp != null) { + try { + return userNameAvp.getUTF8String(); // IE: IMSI mapped to User-Name + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain User-Name AVP value (IMSI)", e); + } + } + return null; + } + + @Override + public boolean isMSISDNAvpPresent() { + return super.message.getAvps().getAvp(Avp.MSISDN) != null; + } + + @Override + public byte[] getMSISDN() { + Avp msisdnAvp = super.message.getAvps().getAvp(Avp.MSISDN); + if (msisdnAvp != null) { + try { + return msisdnAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSISDN AVP value", e); + } + } + return null; + } + + @Override + public boolean isIMEIAvpPresent() { + return super.message.getAvps().getAvp(Avp.TGPP_IMEI) != null; + } + + @Override + public String getIMEI() { + Avp imeiAvp = super.message.getAvps().getAvp(Avp.TGPP_IMEI); + if (imeiAvp != null) { + try { + return imeiAvp.getUTF8String(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain IMEI AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSEPSClientNameAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME) != null; + } + + @Override + public boolean isLSCNameStringAvpPresent() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + return lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_NAME_STRING) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Name-String AVP", e); + } + } + return false; + } + + @Override + public String getLSCNameString() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + Avp lcsNameStringAvp = lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_NAME_STRING); + if (lcsNameStringAvp != null){ + return lcsNameStringAvp.getUTF8String(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Name-String AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSFormatIndicatorAvpPresent() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + return lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_FORMAT_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Format-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getLCSFormatIndicator() { + Avp lcsEPSClientNameAvp = super.message.getAvps().getAvp(Avp.LCS_EPS_CLIENT_NAME); + if (lcsEPSClientNameAvp != null) { + try { + Avp lcsFormatIndicatorAvp = lcsEPSClientNameAvp.getGrouped().getAvp(Avp.LCS_FORMAT_INDICATOR); + if (lcsFormatIndicatorAvp != null){ + return lcsFormatIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Format-Indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSCLientTypeAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_CLIENT_TYPE) != null; + } + + @Override + public int getLCSClientType() { + Avp lcsClientTypeAvp = super.message.getAvps().getAvp(Avp.LCS_CLIENT_TYPE); + if (lcsClientTypeAvp != null) { + try { + return lcsClientTypeAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Client-Type AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSRequestorNamePresent() { + return super.message.getAvps().getAvp(Avp.LCS_REQUESTOR_NAME) != null; + } + + @Override + public boolean isLCSRequestorIdStringAvpPresent() { + Avp lcsRequestorNameAvp = super.message.getAvps().getAvp(Avp.LCS_REQUESTOR_NAME); + if (lcsRequestorNameAvp != null) { + try { + return lcsRequestorNameAvp.getGrouped().getAvp(Avp.LCS_REQUESTOR_ID_STRING) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Requestor-Id-String AVP", e); + } + } + return false; + } + + @Override + public String getLCSRequestorIdString() { + Avp lcsRequestorNameAvp = super.message.getAvps().getAvp(Avp.LCS_REQUESTOR_NAME); + if (lcsRequestorNameAvp != null) { + try { + Avp lcsRequestorIdStringAvp = lcsRequestorNameAvp.getGrouped().getAvp(Avp.LCS_REQUESTOR_ID_STRING); + if (lcsRequestorIdStringAvp != null){ + return lcsRequestorIdStringAvp.getUTF8String(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Requestor-Id-String AVP value", e); + } + } + return null; + } + + @Override + public boolean isReqLCSFormatIndicatorAvpPresent() { + Avp lcsRequestorNameAvp = super.message.getAvps().getAvp(Avp.LCS_REQUESTOR_NAME); + if (lcsRequestorNameAvp != null) { + try { + return lcsRequestorNameAvp.getGrouped().getAvp(Avp.LCS_FORMAT_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Format-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getReqLCSFormatIndicator() { + Avp lcsRequestorNameAvp = super.message.getAvps().getAvp(Avp.LCS_REQUESTOR_NAME); + if (lcsRequestorNameAvp != null) { + try { + Avp lcsFormatIndicatorAvp = lcsRequestorNameAvp.getGrouped().getAvp(Avp.LCS_FORMAT_INDICATOR); + if (lcsFormatIndicatorAvp != null){ + return lcsFormatIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Format-Indicator AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSPriorityPresent() { + return super.message.getAvps().getAvp(Avp.LCS_PRIORITY) != null; + } + + @Override + public long getLCSPriority() { + Avp lcsPriorityAvp = super.message.getAvps().getAvp(Avp.LCS_PRIORITY); + if (lcsPriorityAvp != null) { + try { + return lcsPriorityAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Priority AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSQoSAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_QOS) != null; + } + + @Override + public boolean isLCSQoSClassAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.LCS_QOS_CLASS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-QoS-Class AVP", e); + } + } + return false; + } + + @Override + public int getLCSQoSClass() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSClassAvp = lcsQoSAvp.getGrouped().getAvp(Avp.LCS_QOS_CLASS); + if (lcsQoSClassAvp != null){ + return lcsQoSClassAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-QoS-Class AVP value", e); + } + } + return -1; + } + + @Override + public boolean isHorizontalAccuracyAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.HORIZONTAL_ACCURACY) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Horizontal-Accuracy AVP", e); + } + } + return false; + } + + @Override + public long getHorizontalAccuracy() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSHorizontalAccuracyAvp = lcsQoSAvp.getGrouped().getAvp(Avp.HORIZONTAL_ACCURACY); + if (lcsQoSHorizontalAccuracyAvp != null){ + return lcsQoSHorizontalAccuracyAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Horizontal-Accuracy AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVerticalAccuracyAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_ACCURACY) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Accuracy AVP", e); + } + } + return false; + } + + @Override + public long getVerticalAccuracy() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSVerticalAccuracyAvp = lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_ACCURACY); + if (lcsQoSVerticalAccuracyAvp != null){ + return lcsQoSVerticalAccuracyAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Accuracy AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVerticalRequestedAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_REQUESTED) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Requested AVP", e); + } + } + return false; + } + + public int getVerticalRequested() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSVerticalRequestedAvp = lcsQoSAvp.getGrouped().getAvp(Avp.VERTICAL_REQUESTED); + if (lcsQoSVerticalRequestedAvp != null){ + return lcsQoSVerticalRequestedAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Vertical-Requested AVP value", e); + } + } + return -1; + } + + @Override + public boolean isResponseTimeAvpPresent() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + return lcsQoSAvp.getGrouped().getAvp(Avp.RESPONSE_TIME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Response-Time AVP", e); + } + } + return false; + } + + @Override + public int getResponseTime() { + Avp lcsQoSAvp = super.message.getAvps().getAvp(Avp.LCS_QOS); + if (lcsQoSAvp != null) { + try { + Avp lcsQoSResponseTimeAvp = lcsQoSAvp.getGrouped().getAvp(Avp.RESPONSE_TIME); + if (lcsQoSResponseTimeAvp != null){ + return lcsQoSResponseTimeAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Response-Time AVP value", e); + } + } + return -1; + } + + @Override + public boolean isVelocityRequestedAvpPresent() { + return super.message.getAvps().getAvp(Avp.VELOCITY_REQUESTED) != null; + } + + @Override + public int getVelocityRequested() { + Avp lcsVelocityRequestedAvp = super.message.getAvps().getAvp(Avp.VELOCITY_REQUESTED); + if (lcsVelocityRequestedAvp != null) { + try { + return lcsVelocityRequestedAvp.getInteger32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Velocity-Requested AVP value", e); + } + } + return-1; + } + + @Override + public boolean isSupportedGADShapesAvpPresent() { + return super.message.getAvps().getAvp(Avp.SUPPORTED_GAD_SHAPES) != null; + } + + @Override + public long getSupportedGADSahpes() { + Avp lcsSupportedGADShapesAvp = super.message.getAvps().getAvp(Avp.SUPPORTED_GAD_SHAPES); + if (lcsSupportedGADShapesAvp != null) { + try { + return lcsSupportedGADShapesAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Supported GAD Shapes AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLSCServiceTypeIdAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_SERVICE_TYPE_ID) != null; + } + + @Override + public long getLSCServiceTypeId() { + Avp lcsServiceTypeIdAvp = super.message.getAvps().getAvp(Avp.LCS_SERVICE_TYPE_ID); + if (lcsServiceTypeIdAvp != null) { + try { + return lcsServiceTypeIdAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Service Type ID AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSCodewordAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_CODEWORD) != null; + } + + @Override + public String getLCSCodeword() { + Avp lcsCodewordAvp = super.message.getAvps().getAvp(Avp.LCS_CODEWORD); + if (lcsCodewordAvp != null) { + try { + return lcsCodewordAvp.getUTF8String(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Codeword AVP value", e); + } + } + return null; + } + + @Override + public boolean isServiceSelectionAvpPresent() { + return super.message.getAvps().getAvp(Avp.SERVICE_SELECTION) != null; + } + + @Override + public String getServiceSelection() { + Avp lcsServiceSelectionAvp = super.message.getAvps().getAvp(Avp.SERVICE_SELECTION); + if (lcsServiceSelectionAvp != null) { + try { + return lcsServiceSelectionAvp.getUTF8String(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Service Selection AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSPrivacyCheckSessionAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_PRIVACY_CHECK_SESSION) != null; + } + + @Override + public boolean isLCSPrivacyCheckAvpPresent() { + Avp lcPrivacyCheckSessionAvp = super.message.getAvps().getAvp(Avp.LCS_PRIVACY_CHECK_SESSION); + if (lcPrivacyCheckSessionAvp != null) { + try { + return lcPrivacyCheckSessionAvp.getGrouped().getAvp(Avp.LCS_PRIVACY_CHECK) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Privacy-Check AVP", e); + } + } + return false; + } + + @Override + public int getLCSPrivacyCheck() { + Avp lcPrivacyCheckSessionAvp = super.message.getAvps().getAvp(Avp.LCS_PRIVACY_CHECK_SESSION); + if (lcPrivacyCheckSessionAvp != null) { + try { + Avp lcsPrivacyCheckAvp = lcPrivacyCheckSessionAvp.getGrouped().getAvp(Avp.LCS_PRIVACY_CHECK); + if (lcsPrivacyCheckAvp != null){ + return lcsPrivacyCheckAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Privacy-Check AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSPrivacyCheckNonSessionAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_PRIVACY_CHECK_NON_SESSION) != null; + } + + @Override + public boolean isLCSPrivacyCheckNSAvpPresent() { + Avp lcPrivacyCheckNonSessionAvp = super.message.getAvps().getAvp(Avp.LCS_PRIVACY_CHECK_NON_SESSION); + if (lcPrivacyCheckNonSessionAvp != null) { + try { + return lcPrivacyCheckNonSessionAvp.getGrouped().getAvp(Avp.LCS_PRIVACY_CHECK) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Privacy-Check AVP", e); + } + } + return false; + } + + @Override + public int getLCSPrivacyCheckNS() { + Avp lcPrivacyCheckNonSessionAvp = super.message.getAvps().getAvp(Avp.LCS_PRIVACY_CHECK_NON_SESSION); + if (lcPrivacyCheckNonSessionAvp != null) { + try { + Avp lcsPrivacyCheckAvp = lcPrivacyCheckNonSessionAvp.getGrouped().getAvp(Avp.LCS_PRIVACY_CHECK); + if (lcsPrivacyCheckAvp != null){ + return lcsPrivacyCheckAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Privacy-Check AVP value", e); + } + } + return -1; + } + + @Override + public boolean isDeferredLocationTypeAvpPresent() { + return super.message.getAvps().getAvp(Avp.DEFERRED_LOCATION_TYPE) != null; + } + + @Override + public long getDeferredLocationType() { + Avp lcsDeferredLocationTypeAvp = super.message.getAvps().getAvp(Avp.DEFERRED_LOCATION_TYPE); + if (lcsDeferredLocationTypeAvp != null) { + try { + return lcsDeferredLocationTypeAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Deferred Location Type AVP value", e); + } + } + return -1; + } + + @Override + public boolean isLCSReferenceNumberAvpPresent() { + return super.message.getAvps().getAvp(Avp.LCS_REFERENCE_NUMBER) != null; + } + + @Override + public byte[] getLCSReferenceNumber() { + Avp lcsLCSReferenceNumberAvp = super.message.getAvps().getAvp(Avp.LCS_REFERENCE_NUMBER); + if (lcsLCSReferenceNumberAvp != null) { + try { + return lcsLCSReferenceNumberAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reference Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isAreaEventInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.AREA_EVENT_INFO) != null; + } + + @Override + public boolean isOccurrenceInfoAvpPresent() { + Avp lcsAreaEventInfoAvp = super.message.getAvps().getAvp(Avp.AREA_EVENT_INFO); + if (lcsAreaEventInfoAvp != null) { + try { + return lcsAreaEventInfoAvp.getGrouped().getAvp(Avp.OCCURRENCE_INFO) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Ocurrence-Info AVP", e); + } + } + return false; + } + + @Override + public int getOccurrenceInfo() { + Avp lcsAreaEventInfoAvp = super.message.getAvps().getAvp(Avp.AREA_EVENT_INFO); + if (lcsAreaEventInfoAvp != null) { + try { + Avp lcsOccurrenceInfoAvp = lcsAreaEventInfoAvp.getGrouped().getAvp(Avp.OCCURRENCE_INFO); + if (lcsOccurrenceInfoAvp != null){ + return lcsOccurrenceInfoAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Ocurrence-Info AVP value", e); + } + } + return -1; + } + + @Override + public boolean isIntervalTimeAvpPresent() { + Avp lcsAreaEventInfoAvp = super.message.getAvps().getAvp(Avp.AREA_EVENT_INFO); + if (lcsAreaEventInfoAvp != null) { + try { + return lcsAreaEventInfoAvp.getGrouped().getAvp(Avp.INTERVAL_TIME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Interval-Time AVP", e); + } + } + return false; + } + + @Override + public long getIntervalTime() { + Avp lcsAreaEventInfoAvp = super.message.getAvps().getAvp(Avp.AREA_EVENT_INFO); + if (lcsAreaEventInfoAvp != null) { + try { + Avp lcsIntervalTimeAvp = lcsAreaEventInfoAvp.getGrouped().getAvp(Avp.INTERVAL_TIME); + if (lcsIntervalTimeAvp != null){ + return lcsIntervalTimeAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Interval-Time AVP value", e); + } + } + return -1; + } + + @Override + public boolean isAreaDefinitionAvpPresent() { + Avp lcsAreaEventInfoAvp = super.message.getAvps().getAvp(Avp.AREA_EVENT_INFO); + if (lcsAreaEventInfoAvp != null) { + try { + return lcsAreaEventInfoAvp.getGrouped().getAvp(Avp.AREA_DEFINITION) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Area-Definition AVP", e); + } + } + return false; + } + + @Override + public boolean isAreaTypeAvpPresent() { + Avp lcsAreaDefinitionAvp = super.message.getAvps().getAvp(Avp.AREA_DEFINITION); + if (lcsAreaDefinitionAvp != null) { + try { + return lcsAreaDefinitionAvp.getGrouped().getAvp(Avp.AREA_TYPE) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Area-Type AVP", e); + } + } + return false; + } + + @Override + public long getAreaType() { + Avp lcsAreaDefinitionAvp = super.message.getAvps().getAvp(Avp.AREA_DEFINITION); + if (lcsAreaDefinitionAvp != null) { + try { + Avp lcsAreaTypeAvp = lcsAreaDefinitionAvp.getGrouped().getAvp(Avp.AREA_TYPE); + if (lcsAreaTypeAvp != null){ + return lcsAreaTypeAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Area-Type AVP value", e); + } + } + return -1; + } + + @Override + public boolean isAreaIdentificationAvpPresent() { + Avp lcsAreaDefinitionAvp = super.message.getAvps().getAvp(Avp.AREA_DEFINITION); + if (lcsAreaDefinitionAvp != null) { + try { + return lcsAreaDefinitionAvp.getGrouped().getAvp(Avp.AREA_IDENTIFICATION) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Area-Identification AVP", e); + } + } + return false; + } + + @Override + public byte[] getAreaIdentification() { + Avp lcsAreaDefinitionAvp = super.message.getAvps().getAvp(Avp.AREA_DEFINITION); + if (lcsAreaDefinitionAvp != null) { + try { + Avp lcsAreaIdAvp = lcsAreaDefinitionAvp.getGrouped().getAvp(Avp.AREA_DEFINITION); + if (lcsAreaIdAvp != null){ + return lcsAreaIdAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Area Identification AVP value", e); + } + } + return null; + } + + @Override + public boolean isGMLCAddressAvpPresent() { + return super.message.getAvps().getAvp(Avp.GMLC_ADDRESS) != null; + } + + @Override + public java.net.InetAddress getGMLCAddress() { + Avp lcsGMLCAddressAvp = super.message.getAvps().getAvp(Avp.GMLC_ADDRESS); + if (lcsGMLCAddressAvp != null) { + try { + return lcsGMLCAddressAvp.getAddress(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isPLRFlagsAvpPresent() { + return super.message.getAvps().getAvp(Avp.PLR_FLAGS) != null; + } + + @Override + public long getPLRFLags() { + Avp lcsPLRFlagsAvp = super.message.getAvps().getAvp(Avp.PLR_FLAGS); + if (lcsPLRFlagsAvp != null) { + try { + return lcsPLRFlagsAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS PLR Flags AVP value", e); + } + } + return -1; + } + + @Override + public boolean isPeriodicLDRInfoAvpPresent() { + return super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION) != null; + } + + @Override + public boolean isReportingAmountAvpPresent() { + Avp lcsPeriodicLDRInfo = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfo != null) { + try { + return lcsPeriodicLDRInfo.getGrouped().getAvp(Avp.REPORTING_AMOUNT) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Reporting-Amount AVP", e); + } + } + return false; + } + + @Override + public long getReportingAmount() { + Avp lcsPeriodicLDRInfo = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfo != null) { + try { + Avp lcsReportingAmountAvp = lcsPeriodicLDRInfo.getGrouped().getAvp(Avp.REPORTING_AMOUNT); + if (lcsReportingAmountAvp != null){ + return lcsReportingAmountAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reporting amount AVP value", e); + } + } + return -1; + } + + @Override + public boolean isReportingIntervalAvpPresent() { + Avp lcsPeriodicLDRInfo = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfo != null) { + try { + return lcsPeriodicLDRInfo.getGrouped().getAvp(Avp.REPORTING_INTERVAL) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Reporting-Interval AVP", e); + } + } + return false; + } + + @Override + public long getReportingInterval() { + Avp lcsPeriodicLDRInfo = super.message.getAvps().getAvp(Avp.PERIODIC_LDR_INFORMATION); + if (lcsPeriodicLDRInfo != null) { + try { + Avp lcsReportingIntervalAvp = lcsPeriodicLDRInfo.getGrouped().getAvp(Avp.REPORTING_INTERVAL); + if (lcsReportingIntervalAvp != null){ + return lcsReportingIntervalAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Reporting-Interval AVP value", e); + } + } + return -1; + } + + @Override + public boolean isReportingPLMNListAvpPresent() { + return super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST) != null; + } + + @Override + public boolean isPrioritizedListIndicatorAvpPresent() { + Avp lcsReportingPLMNListAvp = super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST); + if (lcsReportingPLMNListAvp != null) { + try { + return lcsReportingPLMNListAvp.getGrouped().getAvp(Avp.PRIORITIZED_LIST_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Prioritized-List-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getPrioritizedListIndicator() { + Avp lcsReportingPLMNListAvp = super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST); + if (lcsReportingPLMNListAvp != null) { + try { + Avp lcsPrioritizedListIndicatorAvp = lcsReportingPLMNListAvp.getGrouped().getAvp(Avp.PRIORITIZED_LIST_INDICATOR); + if (lcsPrioritizedListIndicatorAvp != null){ + return lcsPrioritizedListIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS GERAN-Positioning-Data AVP value", e); + } + } + return -1; + } + + @Override + public boolean isPLMNIDListAvpPresent() { + Avp lcsReportingPLMNListAvp = super.message.getAvps().getAvp(Avp.REPORTING_PLMN_LIST); + if (lcsReportingPLMNListAvp != null) { + try { + return lcsReportingPLMNListAvp.getGrouped().getAvp(Avp.PLMN_ID_LIST) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain PLMN-Id-List AVP", e); + } + } + return false; + } + + @Override + public boolean isVisitedPLMNIdAvpPresent() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + return lcsPLMNIdListAvp.getGrouped().getAvp(Avp.VISITED_PLMN_ID) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Visited-PLMN-Id AVP", e); + } + } + return false; + } + + @Override + public byte[] getVisitedPLMNId() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + Avp lcsVisitedPLMNIdAvp = lcsPLMNIdListAvp.getGrouped().getAvp(Avp.VISITED_PLMN_ID); + if (lcsVisitedPLMNIdAvp != null){ + return lcsVisitedPLMNIdAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Visited PLMN ID AVP value", e); + } + } + return null; + } + + @Override + public boolean isPeriodicLocationSupportIndicatorAvpPresent() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + return lcsPLMNIdListAvp.getGrouped().getAvp(Avp.PERIODIC_LOCATION_SUPPORT_INDICATOR) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain Periodic-Location-Support-Indicator AVP", e); + } + } + return false; + } + + @Override + public int getPeriodicLocationSupportIndicator() { + Avp lcsPLMNIdListAvp = super.message.getAvps().getAvp(Avp.PLMN_ID_LIST); + if (lcsPLMNIdListAvp != null) { + try { + Avp lcsPeriodicLocationSupportIndicatorAvp = lcsPLMNIdListAvp.getGrouped().getAvp(Avp.PERIODIC_LOCATION_SUPPORT_INDICATOR); + if (lcsPeriodicLocationSupportIndicatorAvp != null){ + return lcsPeriodicLocationSupportIndicatorAvp.getInteger32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS Periodic Location Support Indicator AVP value", e); + } + } + return -1; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataFactory.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataFactory.java new file mode 100644 index 000000000..a249ecc23 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataFactory.java @@ -0,0 +1,73 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.client.impl.app.slg.ClientSLgSessionDataLocalImpl; +import org.jdiameter.common.api.app.IAppSessionDataFactory; +import org.jdiameter.common.api.app.slg.ISLgSessionData; +import org.jdiameter.server.impl.app.slg.ServerSLgSessionDataLocalImpl; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLgLocalSessionDataFactory implements IAppSessionDataFactory { + + public ISLgSessionData getAppSessionData(Class clazz, String sessionId) { + if (clazz.equals(ClientSLgSession.class)) { + ClientSLgSessionDataLocalImpl data = new ClientSLgSessionDataLocalImpl(); + data.setSessionId(sessionId); + return data; + } else if (clazz.equals(ServerSLgSession.class)) { + ServerSLgSessionDataLocalImpl data = new ServerSLgSessionDataLocalImpl(); + data.setSessionId(sessionId); + return data; + } else { + throw new IllegalArgumentException("Invalid Session Class: " + clazz.toString()); + } + } +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataImpl.java new file mode 100644 index 000000000..692f1de47 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgLocalSessionDataImpl.java @@ -0,0 +1,86 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import java.io.Serializable; + +import org.jdiameter.api.Request; +import org.jdiameter.common.api.app.AppSessionDataLocalImpl; +import org.jdiameter.common.api.app.slg.ISLgSessionData; +import org.jdiameter.common.api.app.slg.SLgSessionState; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLgLocalSessionDataImpl extends AppSessionDataLocalImpl implements ISLgSessionData { + + protected SLgSessionState state = SLgSessionState.IDLE; + protected Request buffer; + protected Serializable tsTimerId; + + public void setSLgSessionState(SLgSessionState state) { + this.state = state; + } + + public SLgSessionState getSLgSessionState() { + return this.state; + } + + public Serializable getTsTimerId() { + return this.tsTimerId; + } + + public void setTsTimerId(Serializable tid) { + this.tsTimerId = tid; + } + + public void setBuffer(Request buffer) { + this.buffer = buffer; + } + + public Request getBuffer() { + return this.buffer; + } +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSession.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSession.java new file mode 100644 index 000000000..37e7eb113 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSession.java @@ -0,0 +1,156 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import java.io.Serializable; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.app.StateMachine; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.AppSessionImpl; +import org.jdiameter.common.api.app.slg.ISLgMessageFactory; +import org.jdiameter.common.api.app.slg.ISLgSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public abstract class SLgSession extends AppSessionImpl implements NetworkReqListener, StateMachine { + + public static final int _TX_TIMEOUT = 30 * 1000; + + protected Lock sendAndStateLock = new ReentrantLock(); + + @SuppressWarnings("rawtypes") + protected transient List stateListeners = new CopyOnWriteArrayList(); + protected transient ISLgMessageFactory messageFactory; + + protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; + protected ISLgSessionData sessionData; + + public SLgSession(ISessionFactory sf, ISLgSessionData sessionData) { + super(sf, sessionData); + this.sessionData = sessionData; + } + + @SuppressWarnings("rawtypes") + public void addStateChangeNotification(StateChangeListener listener) { + if (!stateListeners.contains(listener)) { + stateListeners.add(listener); + } + } + + @SuppressWarnings("rawtypes") + public void removeStateChangeNotification(StateChangeListener listener) { + stateListeners.remove(listener); + } + + public boolean isStateless() { + return true; + } + + @Override + public boolean isReplicable() { + return false; + } + + protected void startMsgTimer() { + try { + sendAndStateLock.lock(); + sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); + } finally { + sendAndStateLock.unlock(); + } + } + + protected void cancelMsgTimer() { + try { + sendAndStateLock.lock(); + final Serializable timerId = this.sessionData.getTsTimerId(); + if (timerId == null) { + return; + } + super.timerFacility.cancel(timerId); + this.sessionData.setTsTimerId(null); + } finally { + sendAndStateLock.unlock(); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SLgSession other = (SLgSession) obj; + if (sessionData == null) { + if (other.sessionData != null) { + return false; + } + } else if (!sessionData.equals(other.sessionData)) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSessionFactoryImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSessionFactoryImpl.java new file mode 100644 index 000000000..580155a55 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slg/SLgSessionFactoryImpl.java @@ -0,0 +1,313 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slg; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.SessionFactory; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ClientSLgSessionListener; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.ServerSLgSessionListener; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.client.impl.app.slg.IClientSLgSessionData; +import org.jdiameter.client.impl.app.slg.SLgClientSessionImpl; +import org.jdiameter.common.api.app.IAppSessionDataFactory; +import org.jdiameter.common.api.app.slg.ISLgMessageFactory; +import org.jdiameter.common.api.app.slg.ISLgSessionData; +import org.jdiameter.common.api.app.slg.ISLgSessionFactory; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.jdiameter.server.impl.app.slg.IServerSLgSessionData; +import org.jdiameter.server.impl.app.slg.SLgServerSessionImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLgSessionFactoryImpl implements ISLgSessionFactory, ServerSLgSessionListener, ClientSLgSessionListener, + ISLgMessageFactory, StateChangeListener { + + private static final Logger logger = LoggerFactory.getLogger(SLgSessionFactoryImpl.class); + + protected ISessionFactory sessionFactory; + + protected ServerSLgSessionListener serverSessionListener; + protected ClientSLgSessionListener clientSessionListener; + + protected ISLgMessageFactory messageFactory; + protected StateChangeListener stateListener; + protected ISessionDatasource iss; + protected IAppSessionDataFactory sessionDataFactory; + + public SLgSessionFactoryImpl() { + }; + + public SLgSessionFactoryImpl(SessionFactory sessionFactory) { + super(); + init(sessionFactory); + } + + public void init(SessionFactory sessionFactory) { + this.sessionFactory = (ISessionFactory) sessionFactory; + this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); + this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(ISLgSessionData.class); + } + + /** + * @return the serverSessionListener + */ + public ServerSLgSessionListener getServerSessionListener() { + return serverSessionListener != null ? serverSessionListener : this; + } + + /** + * @param serverSessionListener the serverSessionListener to set + */ + public void setServerSessionListener(ServerSLgSessionListener serverSessionListener) { + this.serverSessionListener = serverSessionListener; + } + + /** + * @return the serverSessionListener + */ + public ClientSLgSessionListener getClientSessionListener() { + return clientSessionListener != null ? clientSessionListener : this; + } + + /** + * @param clientSessionListener theclientSessionListener to set + */ + public void setClientSessionListener(ClientSLgSessionListener clientSessionListener) { + this.clientSessionListener = clientSessionListener; + } + + /** + * @return the messageFactory + */ + public ISLgMessageFactory getMessageFactory() { + return messageFactory != null ? messageFactory : this; + } + + /** + * @param messageFactory the messageFactory to set + */ + public void setMessageFactory(ISLgMessageFactory messageFactory) { + this.messageFactory = messageFactory; + } + + /** + * @return the stateListener + */ + public StateChangeListener getStateListener() { + return stateListener != null ? stateListener : this; + } + + /** + * @param stateListener the stateListener to set + */ + public void setStateListener(StateChangeListener stateListener) { + this.stateListener = stateListener; + } + + public AppSession getSession(String sessionId, Class aClass) { + if (sessionId == null) { + throw new IllegalArgumentException("SessionId must not be null"); + } + if (!this.iss.exists(sessionId)) { + return null; + } + AppSession appSession = null; + try { + if (aClass == ServerSLgSession.class) { + IServerSLgSessionData sessionData = (IServerSLgSessionData) this.sessionDataFactory + .getAppSessionData(ServerSLgSession.class, sessionId); + SLgServerSessionImpl serverSession = new SLgServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, + this.getServerSessionListener()); + serverSession.getSessions().get(0).setRequestListener(serverSession); + appSession = serverSession; + } else if (aClass == ClientSLgSession.class) { + IClientSLgSessionData sessionData = (IClientSLgSessionData) this.sessionDataFactory + .getAppSessionData(ClientSLgSession.class, sessionId); + SLgClientSessionImpl clientSession = new SLgClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, + this.getClientSessionListener()); + clientSession.getSessions().get(0).setRequestListener(clientSession); + appSession = clientSession; + } else { + throw new IllegalArgumentException( + "Wrong session class: " + aClass + ". Supported[" + ServerSLgSession.class + "]"); + } + } catch (Exception e) { + logger.error("Failure to obtain new SLg Session.", e); + } + return appSession; + } + + public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, + Object[] args) { + AppSession appSession = null; + + try { + if (aClass == ServerSLgSession.class) { + if (sessionId == null) { + if (args != null && args.length > 0 && args[0] instanceof Request) { + Request request = (Request) args[0]; + sessionId = request.getSessionId(); + } else { + sessionId = this.sessionFactory.getSessionId(); + } + } + IServerSLgSessionData sessionData = (IServerSLgSessionData) this.sessionDataFactory + .getAppSessionData(ServerSLgSession.class, sessionId); + sessionData.setApplicationId(applicationId); + SLgServerSessionImpl serverSession = new SLgServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, + this.getServerSessionListener()); + + iss.addSession(serverSession); + serverSession.getSessions().get(0).setRequestListener(serverSession); + appSession = serverSession; + } else if (aClass == ClientSLgSession.class) { + if (sessionId == null) { + if (args != null && args.length > 0 && args[0] instanceof Request) { + Request request = (Request) args[0]; + sessionId = request.getSessionId(); + } else { + sessionId = this.sessionFactory.getSessionId(); + } + } + IClientSLgSessionData sessionData = (IClientSLgSessionData) this.sessionDataFactory + .getAppSessionData(ClientSLgSession.class, sessionId); + sessionData.setApplicationId(applicationId); + SLgClientSessionImpl clientSession = new SLgClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, + this.getClientSessionListener()); + + iss.addSession(clientSession); + clientSession.getSessions().get(0).setRequestListener(clientSession); + appSession = clientSession; + } else { + throw new IllegalArgumentException( + "Wrong session class: " + aClass + ". Supported[" + ServerSLgSession.class + "]"); + } + } catch (Exception e) { + logger.error("Failure to obtain new SLg Session.", e); + } + return appSession; + } + + public void stateChanged(Enum oldState, Enum newState) { + logger.info("Diameter SLg Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); + } + + public long getApplicationId() { + return 16777255; + } + + public void stateChanged(AppSession source, Enum oldState, Enum newState) { + logger.info("Diameter SLg Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", + new Object[] { source, oldState, newState }); + } + + public ProvideLocationRequest createProvideLocationRequest(Request request) { + return new ProvideLocationRequestImpl(request); + } + + public ProvideLocationAnswer createProvideLocationAnswer(Answer answer) { + return new ProvideLocationAnswerImpl(answer); + } + + public void doProvideLocationRequestEvent(ServerSLgSession appSession, ProvideLocationRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLg Session Factory :: doProvideLocationRequestEvent :: appSession[{}], Request[{}]", appSession, + request); + } + + public void doProvideLocationAnswerEvent(ClientSLgSession appSession, ProvideLocationRequest request, + ProvideLocationAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLg Session Factory :: doProvideLocationAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", + new Object[] { appSession, request, answer }); + } + + public LocationReportRequest createLocationReportRequest(Request request) { + return new LocationReportRequestImpl(request); + } + + public LocationReportAnswer createLocationReportAnswer(Answer answer) { + return new LocationReportAnswerImpl(answer); + } + + public void doLocationReportRequestEvent(ServerSLgSession appSession, LocationReportRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLg Session Factory :: doLocationReportRequestEvent :: appSession[{}], Request[{}]", appSession, + request); + } + + public void doLocationReportAnswerEvent(ClientSLgSession appSession, LocationReportRequest request, + LocationReportAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLg Session Factory :: doLocationReportAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", + new Object[] { appSession, request, answer }); + } + + public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLg Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", + new Object[] { appSession, request, answer }); + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoAnswerImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoAnswerImpl.java new file mode 100644 index 000000000..c86a222dc --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoAnswerImpl.java @@ -0,0 +1,708 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slh; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.Request; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +// import java.net.InetAddress; + +/** + * @author Fernando Mendioroz + * + */ +public class LCSRoutingInfoAnswerImpl extends AppRequestEventImpl implements LCSRoutingInfoAnswer { + + private static final long serialVersionUID = 1L; + + protected static final Logger logger = LoggerFactory.getLogger(LCSRoutingInfoAnswer.class); + + /** + * + * @param answer + */ + public LCSRoutingInfoAnswerImpl(Answer answer) { + super(answer); + } + + /** + * + * @param request + * @param resultCode + */ + public LCSRoutingInfoAnswerImpl(Request request, long resultCode) { + super(request.createAnswer(resultCode)); + } + + @Override + public boolean isUserNameAVPPresent() { + return super.message.getAvps().getAvp(Avp.USER_NAME) != null; // IE: IMSI mapped to User-Name AVP + } + + @Override + public String getUserName() { + Avp userNameAvp = super.message.getAvps().getAvp(Avp.USER_NAME); + if (userNameAvp != null) { + try { + return userNameAvp.getUTF8String(); // IE: IMSI mapped to User-Name AVP + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain User-Name AVP value (IMSI)", e); + } + } + return null; + } + + @Override + public boolean isMSISDNAVPPresent() { + return super.message.getAvps().getAvp(Avp.MSISDN) != null; + } + + @Override + public byte[] getMSISDN() { + Avp msisdnAvp = super.message.getAvps().getAvp(Avp.MSISDN); + if (msisdnAvp != null) { + try { + return msisdnAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSISDN AVP value", e); + } + } + return null; + } + + @Override + public boolean isLMSIAVPPresent() { + return super.message.getAvps().getAvp(Avp.LMSI) != null; + } + + @Override + public byte[] getLMSI() { + Avp localMobileStationIdentityAvp = super.message.getAvps().getAvp(Avp.LMSI); + if (localMobileStationIdentityAvp != null) { + try { + return localMobileStationIdentityAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LMSI AVP value", e); + } + } + return null; + } + + @Override + public boolean isServingNodeAVPPresent() { + return super.message.getAvps().getAvp(Avp.SERVING_NODE) != null; + } + + @Override + public boolean isSGSNNumberAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getSGSNNumber(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp sgsnNumberAvp = servingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER); + if (sgsnNumberAvp != null){ + return sgsnNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isSGSNNameAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Name AVP", e); + } + } + return false; + } + + @Override + public String getSGSNName(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp sgsnNameAvp = servingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME); + if (sgsnNameAvp != null){ + return sgsnNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isSGSNRealmAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Realm AVP", e); + } + } + return false; + } + + @Override + public String getSGSNRealm(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp sgsnRealmAvp = servingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM); + if (sgsnRealmAvp != null){ + return sgsnRealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isMMENameAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.MME_NAME) != null; + } catch (AvpDataException ex) { + logger.debug("Failure trying to obtain MME-Name AVP", ex); + } + } + return false; + } + + @Override + public String getMMEName(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp mmeNameAvp = servingNodeAvp.getGrouped().getAvp(Avp.MME_NAME); + if (mmeNameAvp != null){ + return mmeNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MME-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isMMERealmAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.MME_REALM) != null; + } catch (AvpDataException ex) { + logger.debug("Failure trying to obtain MME-Realm AVP", ex); + } + } + return false; + } + + @Override + public String getMMERealm(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp mmeRealmAvp = servingNodeAvp.getGrouped().getAvp(Avp.MME_REALM); + if (mmeRealmAvp != null){ + return mmeRealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MME-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isMSCNumberAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSC-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getMSCNumber(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp mscNumberAvp = servingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER); + if (mscNumberAvp != null){ + return mscNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSC-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean is3GPPAAAServerNameAVPPresent() { + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain 3GPP-AAA-Server-Name AVP", e); + } + } + return false; + } + + @Override + public String get3GPPAAAServerName(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp tgppAAAServerNameAvp = servingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME); + if (tgppAAAServerNameAvp != null){ + return tgppAAAServerNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSC-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isLCSCapabilitiesSetsAVPPresent(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets AVP", e); + } + } + return false; + } + + @Override + public long getLCSCapabilitiesSets(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp lcsCapabilitiesSetsAvp = servingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS); + if (lcsCapabilitiesSetsAvp != null){ + return lcsCapabilitiesSetsAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets value", e); + } + } + return -1; + } + + @Override + public boolean isGMLCAddressAVPPresent(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + return servingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC-Address AVP", e); + } + } + return false; + } + + @Override + public java.net.InetAddress getGMLCAddress(){ + Avp servingNodeAvp = super.message.getAvps().getAvp(Avp.SERVING_NODE); + if (servingNodeAvp != null) { + try { + Avp gmlcAddressAvp = servingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS); + if (gmlcAddressAvp != null){ + return gmlcAddressAvp.getAddress(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC-Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalServingNodeAVPPresent(){ + return super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE) != null; + } + + @Override + public boolean isAdditionalSGSNNumberAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getAdditionalSGSNNumber(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp sgsnNumberAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NUMBER); + if (sgsnNumberAvp != null){ + return sgsnNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalSGSNNameAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Name AVP", e); + } + } + return false; + } + + @Override + public String getAdditionalSGSNName(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp sgsnNameAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.SGSN_NAME); + if (sgsnNameAvp != null){ + return sgsnNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalSGSNRealmAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Realm AVP", e); + } + } + return false; + } + + @Override + public String getAdditionalSGSNRealm(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp sgsnRealmAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.SGSN_REALM); + if (sgsnRealmAvp != null){ + return sgsnRealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain SGSN-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalMMENameAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.MME_NAME) != null; + } catch (AvpDataException ex) { + logger.debug("Failure trying to obtain MME-Name AVP", ex); + } + } + return false; + } + + @Override + public String getAdditionalMMEName(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp mmeNameAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.MME_NAME); + if (mmeNameAvp != null){ + return mmeNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MME-Name AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalMMERealmAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.MME_REALM) != null; + } catch (AvpDataException ex) { + logger.debug("Failure trying to obtain MME-Realm AVP", ex); + } + } + return false; + } + + @Override + public String getAdditionalMMERealm(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp mmeRealmAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.MME_REALM); + if (mmeRealmAvp != null){ + return mmeRealmAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MME-Realm AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalMSCNumberAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSC-Number AVP", e); + } + } + return false; + } + + @Override + public byte[] getAdditionalMSCNumber(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp mscNumberAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.MSC_NUMBER); + if (mscNumberAvp != null){ + return mscNumberAvp.getOctetString(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSC-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditional3GPPAAAServerNameAVPPresent() { + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain 3GPP-AAA-Server-Name AVP", e); + } + } + return false; + } + + @Override + public String getAdditional3GPPAAAServerName(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp tgppAAAServerNameAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.TGPP_AAA_SERVER_NAME); + if (tgppAAAServerNameAvp != null){ + return tgppAAAServerNameAvp.getDiameterIdentity(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSC-Number AVP value", e); + } + } + return null; + } + + @Override + public boolean isAdditionalLCSCapabilitiesSetsAVPPresent(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets AVP", e); + } + } + return false; + } + + @Override + public long getAdditionalLCSCapabilitiesSets(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp lcsCapabilitiesSetsAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.LCS_CAPABILITIES_SETS); + if (lcsCapabilitiesSetsAvp != null){ + return lcsCapabilitiesSetsAvp.getUnsigned32(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain LCS-Capabilities-Sets value", e); + } + } + return -1; + } + + @Override + public boolean isAdditionalGMLCAddressAVPPresent(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + return additionalServingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS) != null; + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC-Address AVP", e); + } + } + return false; + } + + @Override + public java.net.InetAddress getAdditionalGMLCAddress(){ + Avp additionalServingNodeAvp = super.message.getAvps().getAvp(Avp.ADDITIONAL_SERVING_NODE); + if (additionalServingNodeAvp != null) { + try { + Avp gmlcAddressAvp = additionalServingNodeAvp.getGrouped().getAvp(Avp.GMLC_ADDRESS); + if (gmlcAddressAvp != null){ + return gmlcAddressAvp.getAddress(); + } + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC-Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isPPRAddressAVPPresent(){ + return super.message.getAvps().getAvp(Avp.PPR_ADDRESS) != null; + } + + @Override + public java.net.InetAddress getPPRAddress(){ + Avp pprAddressAvp = super.message.getAvps().getAvp(Avp.PPR_ADDRESS); + if (pprAddressAvp != null) { + try { + return pprAddressAvp.getAddress(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain PPR-Address AVP value", e); + } + } + return null; + } + + @Override + public boolean isRIAFlagsAVPPresent() { + return super.message.getAvps().getAvp(Avp.RIA_FLAGS) != null; + } + + @Override + public long getRIAFLags(){ + Avp riaFlagsAvp = super.message.getAvps().getAvp(Avp.RIA_FLAGS); + if (riaFlagsAvp != null) { + try { + return riaFlagsAvp.getUnsigned32(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain RIA-FLAGS AVP value", e); + } + } + return -1; + } + + public Avp getResultCodeAvp() throws AvpDataException { + return null; + } + +} diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoRequestImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoRequestImpl.java new file mode 100644 index 000000000..f25df0a36 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/LCSRoutingInfoRequestImpl.java @@ -0,0 +1,122 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slh; + +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpDataException; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.jdiameter.api.Message; + +/** + * @author Fernando Mendioroz + * + */ +public class LCSRoutingInfoRequestImpl extends AppRequestEventImpl implements LCSRoutingInfoRequest { + + private static final long serialVersionUID = 1L; + + protected static final Logger logger = LoggerFactory.getLogger(LCSRoutingInfoRequestImpl.class); + + public LCSRoutingInfoRequestImpl(Message message) { + super(message); + message.setRequest(true); + } + + @Override + public boolean isUserNameAVPPresent() { + return super.message.getAvps().getAvp(Avp.USER_NAME) != null; // IE: IMSI + } + + @Override + public String getUserName() { + Avp userNameAvp = super.message.getAvps().getAvp(Avp.USER_NAME); + if (userNameAvp != null) { + try { + return userNameAvp.getUTF8String(); // IE: IMSI mapped to User-Name + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain User-Name AVP value (IMSI)", e); + } + } + return null; + } + + @Override + public boolean isMSISDNAVPPresent() { + return super.message.getAvps().getAvp(Avp.MSISDN) != null; + } + + @Override + public byte[] getMSISDN() { + Avp msisdnAvp = super.message.getAvps().getAvp(Avp.MSISDN); + if (msisdnAvp != null) { + try { + return msisdnAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain MSISDN AVP value", e); + } + } + return null; + } + + @Override + public boolean isGMLCNumberAVPPresent() { + return super.message.getAvps().getAvp(Avp.GMLC_NUMBER) != null; + } + + @Override + public byte[] getGMLCNumber() { + Avp gmlcNumberAvp = super.message.getAvps().getAvp(Avp.GMLC_NUMBER); + if (gmlcNumberAvp != null) { + try { + return gmlcNumberAvp.getOctetString(); + } catch (AvpDataException e) { + logger.debug("Failure trying to obtain GMLC-Number AVP value", e); + } + } + return null; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataFactory.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataFactory.java new file mode 100644 index 000000000..30ec4e5cf --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataFactory.java @@ -0,0 +1,73 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slh; + +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.client.impl.app.slh.ClientSLhSessionDataLocalImpl; +import org.jdiameter.common.api.app.IAppSessionDataFactory; +import org.jdiameter.common.api.app.slh.ISLhSessionData; +import org.jdiameter.server.impl.app.slh.ServerSLhSessionDataLocalImpl; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLhLocalSessionDataFactory implements IAppSessionDataFactory { + + public ISLhSessionData getAppSessionData(Class clazz, String sessionId) { + if (clazz.equals(ClientSLhSession.class)) { + ClientSLhSessionDataLocalImpl data = new ClientSLhSessionDataLocalImpl(); + data.setSessionId(sessionId); + return data; + } else if (clazz.equals(ServerSLhSession.class)) { + ServerSLhSessionDataLocalImpl data = new ServerSLhSessionDataLocalImpl(); + data.setSessionId(sessionId); + return data; + } else { + throw new IllegalArgumentException("Invalid Session Class: " + clazz.toString()); + } + } +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataImpl.java new file mode 100644 index 000000000..0211ef5be --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhLocalSessionDataImpl.java @@ -0,0 +1,87 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slh; + +import java.io.Serializable; + +import org.jdiameter.api.Request; +import org.jdiameter.common.api.app.AppSessionDataLocalImpl; +import org.jdiameter.common.api.app.slh.ISLhSessionData; +import org.jdiameter.common.api.app.slh.SLhSessionState; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLhLocalSessionDataImpl extends AppSessionDataLocalImpl implements ISLhSessionData { + + protected SLhSessionState state = SLhSessionState.IDLE; + protected Request buffer; + protected Serializable tsTimerId; + + public void setSLhSessionState(SLhSessionState state) { + this.state = state; + } + + public SLhSessionState getSLhSessionState() { + return this.state; + } + + public Serializable getTsTimerId() { + return this.tsTimerId; + } + + public void setTsTimerId(Serializable tid) { + this.tsTimerId = tid; + } + + public void setBuffer(Request buffer) { + this.buffer = buffer; + } + + public Request getBuffer() { + return this.buffer; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSession.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSession.java new file mode 100644 index 000000000..5ebc92f9c --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSession.java @@ -0,0 +1,156 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slh; + +import java.io.Serializable; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.app.StateMachine; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.AppSessionImpl; +import org.jdiameter.common.api.app.slh.ISLhMessageFactory; +import org.jdiameter.common.api.app.slh.ISLhSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public abstract class SLhSession extends AppSessionImpl implements NetworkReqListener, StateMachine { + + public static final int _TX_TIMEOUT = 30 * 1000; + + protected Lock sendAndStateLock = new ReentrantLock(); + + @SuppressWarnings("rawtypes") + protected transient List stateListeners = new CopyOnWriteArrayList(); + protected transient ISLhMessageFactory messageFactory; + + protected static final String TIMER_NAME_MSG_TIMEOUT = "MSG_TIMEOUT"; + protected ISLhSessionData sessionData; + + public SLhSession(ISessionFactory sf, ISLhSessionData sessionData) { + super(sf, sessionData); + this.sessionData = sessionData; + } + + @SuppressWarnings("rawtypes") + public void addStateChangeNotification(StateChangeListener listener) { + if (!stateListeners.contains(listener)) { + stateListeners.add(listener); + } + } + + @SuppressWarnings("rawtypes") + public void removeStateChangeNotification(StateChangeListener listener) { + stateListeners.remove(listener); + } + + public boolean isStateless() { + return true; + } + + @Override + public boolean isReplicable() { + return false; + } + + protected void startMsgTimer() { + try { + sendAndStateLock.lock(); + sessionData.setTsTimerId(super.timerFacility.schedule(getSessionId(), TIMER_NAME_MSG_TIMEOUT, _TX_TIMEOUT)); + } finally { + sendAndStateLock.unlock(); + } + } + + protected void cancelMsgTimer() { + try { + sendAndStateLock.lock(); + final Serializable timerId = this.sessionData.getTsTimerId(); + if (timerId == null) { + return; + } + super.timerFacility.cancel(timerId); + this.sessionData.setTsTimerId(null); + } finally { + sendAndStateLock.unlock(); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((sessionData == null) ? 0 : sessionData.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SLhSession other = (SLhSession) obj; + if (sessionData == null) { + if (other.sessionData != null) { + return false; + } + } else if (!sessionData.equals(other.sessionData)) { + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSessionFactoryImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSessionFactoryImpl.java new file mode 100644 index 000000000..b7224f6d9 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/app/slh/SLhSessionFactoryImpl.java @@ -0,0 +1,278 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.common.impl.app.slh; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.SessionFactory; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ClientSLhSessionListener; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.api.slh.ServerSLhSessionListener; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.client.impl.app.slh.IClientSLhSessionData; +import org.jdiameter.client.impl.app.slh.SLhClientSessionImpl; +import org.jdiameter.common.api.app.IAppSessionDataFactory; +import org.jdiameter.common.api.app.slh.ISLhMessageFactory; +import org.jdiameter.common.api.app.slh.ISLhSessionData; +import org.jdiameter.common.api.app.slh.ISLhSessionFactory; +import org.jdiameter.common.api.data.ISessionDatasource; +import org.jdiameter.server.impl.app.slh.IServerSLhSessionData; +import org.jdiameter.server.impl.app.slh.SLhServerSessionImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLhSessionFactoryImpl implements ISLhSessionFactory, ServerSLhSessionListener, ClientSLhSessionListener, + ISLhMessageFactory, StateChangeListener { + + private static final Logger logger = LoggerFactory.getLogger(SLhSessionFactoryImpl.class); + + protected ISessionFactory sessionFactory; + + protected ServerSLhSessionListener serverSessionListener; + protected ClientSLhSessionListener clientSessionListener; + + protected ISLhMessageFactory messageFactory; + protected StateChangeListener stateListener; + protected ISessionDatasource iss; + protected IAppSessionDataFactory sessionDataFactory; + + public SLhSessionFactoryImpl() { + }; + + public SLhSessionFactoryImpl(SessionFactory sessionFactory) { + super(); + init(sessionFactory); + } + + public void init(SessionFactory sessionFactory) { + this.sessionFactory = (ISessionFactory) sessionFactory; + this.iss = this.sessionFactory.getContainer().getAssemblerFacility().getComponentInstance(ISessionDatasource.class); + this.sessionDataFactory = (IAppSessionDataFactory) this.iss.getDataFactory(ISLhSessionData.class); + } + + /** + * @return the serverSessionListener + */ + public ServerSLhSessionListener getServerSessionListener() { + return serverSessionListener != null ? serverSessionListener : this; + } + + /** + * @param serverSessionListener the serverSessionListener to set + */ + public void setServerSessionListener(ServerSLhSessionListener serverSessionListener) { + this.serverSessionListener = serverSessionListener; + } + + /** + * @return the serverSessionListener + */ + public ClientSLhSessionListener getClientSessionListener() { + return clientSessionListener != null ? clientSessionListener : this; + } + + /** + * @param clientSessionListener the clientSessionListener to set + */ + public void setClientSessionListener(ClientSLhSessionListener clientSessionListener) { + this.clientSessionListener = clientSessionListener; + } + + /** + * @return the messageFactory + */ + public ISLhMessageFactory getMessageFactory() { + return messageFactory != null ? messageFactory : this; + } + + /** + * @param messageFactory the messageFactory to set + */ + public void setMessageFactory(ISLhMessageFactory messageFactory) { + this.messageFactory = messageFactory; + } + + /** + * @return the stateListener + */ + public StateChangeListener getStateListener() { + return stateListener != null ? stateListener : this; + } + + /** + * @param stateListener the stateListener to set + */ + public void setStateListener(StateChangeListener stateListener) { + this.stateListener = stateListener; + } + + public AppSession getSession(String sessionId, Class aClass) { + if (sessionId == null) { + throw new IllegalArgumentException("SessionId must not be null"); + } + if (!this.iss.exists(sessionId)) { + return null; + } + AppSession appSession = null; + try { + if (aClass == ServerSLhSession.class) { + IServerSLhSessionData sessionData = (IServerSLhSessionData) this.sessionDataFactory.getAppSessionData(ServerSLhSession.class, sessionId); + SLhServerSessionImpl serverSession = new SLhServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); + serverSession.getSessions().get(0).setRequestListener(serverSession); + appSession = serverSession; + } else if (aClass == ClientSLhSession.class) { + IClientSLhSessionData sessionData = (IClientSLhSessionData) this.sessionDataFactory.getAppSessionData(ClientSLhSession.class, sessionId); + SLhClientSessionImpl clientSession = new SLhClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); + clientSession.getSessions().get(0).setRequestListener(clientSession); + appSession = clientSession; + } else { + throw new IllegalArgumentException( + "Wrong session class: " + aClass + ". Supported[" + ServerSLhSession.class + "]"); + } + } catch (Exception e) { + logger.error("Failure to obtain new SLh Session.", e); + } + return appSession; + } + + public AppSession getNewSession(String sessionId, Class aClass, ApplicationId applicationId, Object[] args) { + AppSession appSession = null; + + try { + if (aClass == ServerSLhSession.class) { + if (sessionId == null) { + if (args != null && args.length > 0 && args[0] instanceof Request) { + Request request = (Request) args[0]; + sessionId = request.getSessionId(); + } else { + sessionId = this.sessionFactory.getSessionId(); + } + } + IServerSLhSessionData sessionData = (IServerSLhSessionData) this.sessionDataFactory.getAppSessionData(ServerSLhSession.class, sessionId); + sessionData.setApplicationId(applicationId); + SLhServerSessionImpl serverSession = new SLhServerSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getServerSessionListener()); + + iss.addSession(serverSession); + serverSession.getSessions().get(0).setRequestListener(serverSession); + appSession = serverSession; + } else if (aClass == ClientSLhSession.class) { + if (sessionId == null) { + if (args != null && args.length > 0 && args[0] instanceof Request) { + Request request = (Request) args[0]; + sessionId = request.getSessionId(); + } else { + sessionId = this.sessionFactory.getSessionId(); + } + } + IClientSLhSessionData sessionData = (IClientSLhSessionData) this.sessionDataFactory.getAppSessionData(ClientSLhSession.class, sessionId); + sessionData.setApplicationId(applicationId); + SLhClientSessionImpl clientSession = new SLhClientSessionImpl(sessionData, getMessageFactory(), sessionFactory, this.getClientSessionListener()); + + iss.addSession(clientSession); + clientSession.getSessions().get(0).setRequestListener(clientSession); + appSession = clientSession; + } else { + throw new IllegalArgumentException( + "Wrong session class: " + aClass + ". Supported[" + ServerSLhSession.class + "]"); + } + } catch (Exception e) { + logger.error("Failure to obtain new SLh Session.", e); + } + return appSession; + } + + public void stateChanged(Enum oldState, Enum newState) { + logger.info("Diameter SLh Session Factory :: stateChanged :: oldState[{}], newState[{}]", oldState, newState); + } + + public long getApplicationId() { + return 16777291; + } + + public void stateChanged(AppSession source, Enum oldState, Enum newState) { + logger.info("Diameter SLh Session Factory :: stateChanged :: Session, [{}], oldState[{}], newState[{}]", new Object[] { source, oldState, newState }); + } + + public LCSRoutingInfoAnswer createLCSRoutingInfoAnswer(Answer answer) { + return new LCSRoutingInfoAnswerImpl(answer); + } + + public LCSRoutingInfoRequest createLCSRoutingInfoRequest(Request request) { + return new LCSRoutingInfoRequestImpl(request); + } + + public void doLCSRoutingInfoRequestEvent(ServerSLhSession appSession, LCSRoutingInfoRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLh Session Factory :: doLCSRoutingInfoRequestEvent :: appSession[{}], Request[{}]", appSession, request); + } + + public void doOtherEvent(AppSession appSession, AppRequestEvent request, AppAnswerEvent answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info("Diameter SLh Session Factory :: doOtherEvent :: appSession[{}], Request[{}], Answer[{}]", new Object[] { appSession, request, answer }); + } + + public void doLCSRoutingInfoAnswerEvent(ClientSLhSession appSession, LCSRoutingInfoRequest request, LCSRoutingInfoAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + logger.info( + "Diameter SLh Session Factory :: doLCSRoutingInfoAnswerEvent :: appSession[{}], Request[{}], Answer[{}]", + new Object[] { appSession, request, answer }); + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java index d066798e6..017451023 100644 --- a/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/common/impl/data/LocalDataSource.java @@ -62,6 +62,8 @@ import org.jdiameter.common.api.app.s13.IS13SessionData; import org.jdiameter.common.api.app.s6a.IS6aSessionData; import org.jdiameter.common.api.app.sh.IShSessionData; +import org.jdiameter.common.api.app.slg.ISLgSessionData; +import org.jdiameter.common.api.app.slh.ISLhSessionData; import org.jdiameter.common.api.data.ISessionDatasource; import org.jdiameter.common.impl.app.acc.AccLocalSessionDataFactory; import org.jdiameter.common.impl.app.auth.AuthLocalSessionDataFactory; @@ -74,6 +76,8 @@ import org.jdiameter.common.impl.app.s13.S13LocalSessionDataFactory; import org.jdiameter.common.impl.app.s6a.S6aLocalSessionDataFactory; import org.jdiameter.common.impl.app.sh.ShLocalSessionDataFactory; +import org.jdiameter.common.impl.app.slg.SLgLocalSessionDataFactory; +import org.jdiameter.common.impl.app.slh.SLhLocalSessionDataFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,6 +109,8 @@ public LocalDataSource() { appSessionDataFactories.put(IRxSessionData.class, new RxLocalSessionDataFactory()); appSessionDataFactories.put(IS6aSessionData.class, new S6aLocalSessionDataFactory()); appSessionDataFactories.put(IS13SessionData.class, new S13LocalSessionDataFactory()); + appSessionDataFactories.put(ISLhSessionData.class, new SLhLocalSessionDataFactory()); + appSessionDataFactories.put(ISLgSessionData.class, new SLgLocalSessionDataFactory()); } public LocalDataSource(IContainer container) { diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/Event.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/Event.java new file mode 100644 index 000000000..68066d7f3 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/Event.java @@ -0,0 +1,108 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slg; + +import org.jdiameter.api.InternalException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateEvent; + +/** + * @author Fernando Mendioroz + * + */ + +public class Event implements StateEvent { + + enum Type { + SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_PLR, RECEIVE_LRR + } + + AppEvent request; + AppEvent answer; + Type type; + + Event(Type type, AppEvent request, AppEvent answer) { + this.type = type; + this.answer = answer; + this.request = request; + } + + @SuppressWarnings("unchecked") + public E encodeType(Class eClass) { + return eClass == Type.class ? (E) type : null; + } + + @SuppressWarnings("rawtypes") + public Enum getType() { + return type; + } + + public AppEvent getRequest() { + return request; + } + + public AppEvent getAnswer() { + return answer; + } + + public int compareTo(Object o) { + return 0; + } + + public Object getData() { + return request != null ? request : answer; + } + + public void setData(Object data) { + try { + if (((AppEvent) data).getMessage().isRequest()) { + request = (AppEvent) data; + } else { + answer = (AppEvent) data; + } + } catch (InternalException e) { + throw new IllegalArgumentException(e); + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/IServerSLgSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/IServerSLgSessionData.java new file mode 100644 index 000000000..cf1315a52 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/IServerSLgSessionData.java @@ -0,0 +1,54 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slg; + +import org.jdiameter.common.api.app.slg.ISLgSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public interface IServerSLgSessionData extends ISLgSessionData { + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/SLgServerSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/SLgServerSessionImpl.java new file mode 100644 index 000000000..0548280a2 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/SLgServerSessionImpl.java @@ -0,0 +1,333 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slg; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.EventListener; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.app.StateEvent; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.ServerSLgSessionListener; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.api.app.slg.ISLgMessageFactory; +import org.jdiameter.common.api.app.slg.SLgSessionState; +import org.jdiameter.common.impl.app.AppAnswerEventImpl; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.jdiameter.common.impl.app.slg.SLgSession; +import org.jdiameter.server.impl.app.slg.Event.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLgServerSessionImpl extends SLgSession + implements ServerSLgSession, EventListener, NetworkReqListener { + + private static final Logger logger = LoggerFactory.getLogger(SLgServerSessionImpl.class); + + // Factories and Listeners + // -------------------------------------------------- + private transient ServerSLgSessionListener listener; + protected long appId = -1; + protected IServerSLgSessionData sessionData; + + public SLgServerSessionImpl(IServerSLgSessionData sessionData, ISLgMessageFactory fct, ISessionFactory sf, + ServerSLgSessionListener lst) { + super(sf, sessionData); + if (lst == null) { + throw new IllegalArgumentException("Listener can not be null"); + } + if ((this.appId = fct.getApplicationId()) < 0) { + throw new IllegalArgumentException("ApplicationId can not be less than zero"); + } + + this.listener = lst; + super.messageFactory = fct; + this.sessionData = sessionData; + } + + public void sendProvideLocationAnswer(ProvideLocationAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + send(Event.Type.SEND_MESSAGE, null, answer); + } + + public void sendLocationReportAnswer(LocationReportAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + send(Event.Type.SEND_MESSAGE, null, answer); + } + + @SuppressWarnings("unchecked") + public E getState(Class stateType) { + return stateType == SLgSessionState.class ? (E) this.sessionData.getSLgSessionState() : null; + } + + @SuppressWarnings("unused") + public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { + try { + sendAndStateLock.lock(); + if (!super.session.isValid()) { + // FIXME: throw new InternalException("Generic session is not valid."); + return false; + } + final SLgSessionState state = this.sessionData.getSLgSessionState(); + SLgSessionState newState = null; + Event localEvent = (Event) event; + Event.Type eventType = (Type) event.getType(); + + switch (state) { + + case IDLE: + switch (eventType) { + + case RECEIVE_PLR: + this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); + super.cancelMsgTimer(); + super.startMsgTimer(); + newState = SLgSessionState.MESSAGE_SENT_RECEIVED; + setState(newState); + listener.doProvideLocationRequestEvent(this, (ProvideLocationRequest) event.getData()); + break; + + case RECEIVE_LRR: + this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); + super.cancelMsgTimer(); + super.startMsgTimer(); + newState = SLgSessionState.MESSAGE_SENT_RECEIVED; + setState(newState); + listener.doLocationReportRequestEvent(this, (LocationReportRequest) event.getData()); + break; + + case SEND_MESSAGE: + super.session.send(((AppEvent) event.getData()).getMessage(), this); + newState = SLgSessionState.MESSAGE_SENT_RECEIVED; + setState(newState); + break; + + default: + logger.error("Wrong action in SLg Server FSM. State: IDLE, Event Type: {}", eventType); + break; + } + break; + + case MESSAGE_SENT_RECEIVED: + switch (eventType) { + case TIMEOUT_EXPIRES: + newState = SLgSessionState.TIMEDOUT; + setState(newState); + break; + + case SEND_MESSAGE: + try { + super.session.send(((AppEvent) event.getData()).getMessage(), this); + } finally { + newState = SLgSessionState.TERMINATED; + setState(newState); + } + break; + + default: + throw new InternalException( + "Should not receive more messages after initial. Command: " + event.getData()); + } + break; + + case TERMINATED: + throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); + + case TIMEDOUT: + throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); + + default: + logger.error("SLg Server FSM in wrong state: {}", state); + break; + } + } catch (Exception e) { + throw new InternalException(e); + } finally { + sendAndStateLock.unlock(); + } + return true; + } + + public void receivedSuccessMessage(Request request, Answer answer) { + AnswerDelivery rd = new AnswerDelivery(); + rd.session = this; + rd.request = request; + rd.answer = answer; + super.scheduler.execute(rd); + } + + public void timeoutExpired(Request request) { + try { + handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); + } catch (Exception e) { + logger.debug("Failed to process timeout message", e); + } + } + + public Answer processRequest(Request request) { + RequestDelivery rd = new RequestDelivery(); + rd.session = this; + rd.request = request; + super.scheduler.execute(rd); + return null; + } + + protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { + try { + if (type != null) { + handleEvent(new Event(type, request, answer)); + } + } catch (Exception e) { + throw new InternalException(e); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void setState(SLgSessionState newState) { + SLgSessionState oldState = this.sessionData.getSLgSessionState(); + this.sessionData.setSLgSessionState(newState); + + for (StateChangeListener i : stateListeners) { + i.stateChanged(this, (Enum) oldState, (Enum) newState); + } + if (newState == SLgSessionState.TERMINATED || newState == SLgSessionState.TIMEDOUT) { + super.cancelMsgTimer(); + this.release(); + } + } + + @Override + public void onTimer(String timerName) { + if (timerName.equals(SLgSession.TIMER_NAME_MSG_TIMEOUT)) { + try { + sendAndStateLock.lock(); + try { + handleEvent( + new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); + } catch (Exception e) { + logger.debug("Failure handling Timeout event."); + } + this.sessionData.setBuffer(null); + this.sessionData.setTsTimerId(null); + } finally { + sendAndStateLock.unlock(); + } + } + } + + public void release() { + if (isValid()) { + try { + sendAndStateLock.lock(); + super.release(); + } catch (Exception e) { + logger.debug("Failed to release session", e); + } finally { + sendAndStateLock.unlock(); + } + } else { + logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); + } + } + + private class RequestDelivery implements Runnable { + ServerSLgSession session; + Request request; + + public void run() { + try { + switch (request.getCommandCode()) { + case ProvideLocationRequest.code: + handleEvent( + new Event(Event.Type.RECEIVE_PLR, messageFactory.createProvideLocationRequest(request), null)); + break; + + case LocationReportRequest.code: + handleEvent( + new Event(Event.Type.RECEIVE_LRR, messageFactory.createLocationReportRequest(request), null)); + break; + + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), null); + break; + } + } catch (Exception e) { + logger.debug("Failed to process request message", e); + } + } + } + + private class AnswerDelivery implements Runnable { + ServerSLgSession session; + Answer answer; + Request request; + + public void run() { + try { + switch (answer.getCommandCode()) { + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); + break; + } + } catch (Exception e) { + logger.debug("Failed to process success message", e); + } + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/ServerSLgSessionDataLocalImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/ServerSLgSessionDataLocalImpl.java new file mode 100644 index 000000000..3dc1fa092 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slg/ServerSLgSessionDataLocalImpl.java @@ -0,0 +1,57 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slg; + +import org.jdiameter.common.impl.app.slg.SLgLocalSessionDataImpl; + +/** + * @author Fernando Mendioroz + * + */ + +public class ServerSLgSessionDataLocalImpl extends SLgLocalSessionDataImpl implements IServerSLgSessionData { + + public ServerSLgSessionDataLocalImpl() { + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/Event.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/Event.java new file mode 100644 index 000000000..71984c8bc --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/Event.java @@ -0,0 +1,107 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slh; + +import org.jdiameter.api.InternalException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateEvent; + +/** + * @author Fernando Mendioroz + * + */ + +public class Event implements StateEvent { + enum Type { + SEND_MESSAGE, TIMEOUT_EXPIRES, RECEIVE_RIR; + } + + AppEvent request; + AppEvent answer; + Type type; + + Event(Type type, AppEvent request, AppEvent answer) { + this.type = type; + this.answer = answer; + this.request = request; + } + + @SuppressWarnings("unchecked") + public E encodeType(Class eClass) { + return eClass == Type.class ? (E) type : null; + } + + @SuppressWarnings("rawtypes") + public Enum getType() { + return type; + } + + public AppEvent getRequest() { + return request; + } + + public AppEvent getAnswer() { + return answer; + } + + public int compareTo(Object o) { + return 0; + } + + public Object getData() { + return request != null ? request : answer; + } + + public void setData(Object data) { + try { + if (((AppEvent) data).getMessage().isRequest()) { + request = (AppEvent) data; + } else { + answer = (AppEvent) data; + } + } catch (InternalException e) { + throw new IllegalArgumentException(e); + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/IServerSLhSessionData.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/IServerSLhSessionData.java new file mode 100644 index 000000000..e61de6d40 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/IServerSLhSessionData.java @@ -0,0 +1,54 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slh; + +import org.jdiameter.common.api.app.slh.ISLhSessionData; + +/** + * @author Fernando Mendioroz + * + */ + +public interface IServerSLhSessionData extends ISLhSessionData { + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/SLhServerSessionImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/SLhServerSessionImpl.java new file mode 100644 index 000000000..2f7e63d99 --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/SLhServerSessionImpl.java @@ -0,0 +1,310 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slh; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.EventListener; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppEvent; +import org.jdiameter.api.app.StateChangeListener; +import org.jdiameter.api.app.StateEvent; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.api.slh.ServerSLhSessionListener; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.api.app.slh.ISLhMessageFactory; +import org.jdiameter.common.api.app.slh.SLhSessionState; +import org.jdiameter.common.impl.app.AppAnswerEventImpl; +import org.jdiameter.common.impl.app.AppRequestEventImpl; +import org.jdiameter.common.impl.app.slh.SLhSession; +import org.jdiameter.server.impl.app.slh.Event.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Fernando Mendioroz + * + */ + +public class SLhServerSessionImpl extends SLhSession implements ServerSLhSession, EventListener, NetworkReqListener { + + private static final Logger logger = LoggerFactory.getLogger(SLhServerSessionImpl.class); + + // Factories and Listeners + // -------------------------------------------------- + private transient ServerSLhSessionListener listener; + protected long appId = -1; + protected IServerSLhSessionData sessionData; + + public SLhServerSessionImpl(IServerSLhSessionData sessionData, ISLhMessageFactory fct, ISessionFactory sf, ServerSLhSessionListener lst) { + super(sf, sessionData); + if (lst == null) { + throw new IllegalArgumentException("Listener can not be null"); + } + if ((this.appId = fct.getApplicationId()) < 0) { + throw new IllegalArgumentException("ApplicationId can not be less than zero"); + } + + this.listener = lst; + super.messageFactory = fct; + this.sessionData = sessionData; + } + + public void sendLCSRoutingInfoAnswer(LCSRoutingInfoAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + send(Event.Type.SEND_MESSAGE, null, answer); + } + + @SuppressWarnings("unchecked") + public E getState(Class stateType) { + return stateType == SLhSessionState.class ? (E) this.sessionData.getSLhSessionState() : null; + } + + @SuppressWarnings("unused") + public boolean handleEvent(StateEvent event) throws InternalException, OverloadException { + try { + sendAndStateLock.lock(); + if (!super.session.isValid()) { + // FIXME: throw new InternalException("Generic session is not valid."); + return false; + } + final SLhSessionState state = this.sessionData.getSLhSessionState(); + SLhSessionState newState = null; + Event localEvent = (Event) event; + Event.Type eventType = (Type) event.getType(); + + switch (state) { + + case IDLE: + switch (eventType) { + + case RECEIVE_RIR: + this.sessionData.setBuffer((Request) ((AppEvent) event.getData()).getMessage()); + super.cancelMsgTimer(); + super.startMsgTimer(); + newState = SLhSessionState.MESSAGE_SENT_RECEIVED; + setState(newState); + listener.doLCSRoutingInfoRequestEvent(this, (LCSRoutingInfoRequest) event.getData()); + break; + + case SEND_MESSAGE: + super.session.send(((AppEvent) event.getData()).getMessage(), this); + newState = SLhSessionState.MESSAGE_SENT_RECEIVED; + setState(newState); + break; + + default: + logger.error("Wrong action in SLh Server FSM. State: IDLE, Event Type: {}", eventType); + break; + } + break; + + case MESSAGE_SENT_RECEIVED: + switch (eventType) { + case TIMEOUT_EXPIRES: + newState = SLhSessionState.TIMEDOUT; + setState(newState); + break; + + case SEND_MESSAGE: + try { + super.session.send(((AppEvent) event.getData()).getMessage(), this); + } finally { + newState = SLhSessionState.TERMINATED; + setState(newState); + } + break; + + default: + throw new InternalException( + "Should not receive more messages after initial. Command: " + event.getData()); + } + break; + + case TERMINATED: + throw new InternalException("Cant receive message in state TERMINATED. Command: " + event.getData()); + + case TIMEDOUT: + throw new InternalException("Cant receive message in state TIMEDOUT. Command: " + event.getData()); + + default: + logger.error("SLh Server FSM in wrong state: {}", state); + break; + } + } catch (Exception e) { + throw new InternalException(e); + } finally { + sendAndStateLock.unlock(); + } + return true; + } + + public void receivedSuccessMessage(Request request, Answer answer) { + AnswerDelivery rd = new AnswerDelivery(); + rd.session = this; + rd.request = request; + rd.answer = answer; + super.scheduler.execute(rd); + } + + public void timeoutExpired(Request request) { + try { + handleEvent(new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(request), null)); + } catch (Exception e) { + logger.debug("Failed to process timeout message", e); + } + } + + public Answer processRequest(Request request) { + RequestDelivery rd = new RequestDelivery(); + rd.session = this; + rd.request = request; + super.scheduler.execute(rd); + return null; + } + + protected void send(Event.Type type, AppEvent request, AppEvent answer) throws InternalException { + try { + if (type != null) { + handleEvent(new Event(type, request, answer)); + } + } catch (Exception e) { + throw new InternalException(e); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void setState(SLhSessionState newState) { + SLhSessionState oldState = this.sessionData.getSLhSessionState(); + this.sessionData.setSLhSessionState(newState); + + for (StateChangeListener i : stateListeners) { + i.stateChanged(this, (Enum) oldState, (Enum) newState); + } + if (newState == SLhSessionState.TERMINATED || newState == SLhSessionState.TIMEDOUT) { + super.cancelMsgTimer(); + this.release(); + } + } + + @Override + public void onTimer(String timerName) { + if (timerName.equals(SLhSession.TIMER_NAME_MSG_TIMEOUT)) { + try { + sendAndStateLock.lock(); + try { + handleEvent( + new Event(Event.Type.TIMEOUT_EXPIRES, new AppRequestEventImpl(this.sessionData.getBuffer()), null)); + } catch (Exception e) { + logger.debug("Failure handling Timeout event."); + } + this.sessionData.setBuffer(null); + this.sessionData.setTsTimerId(null); + } finally { + sendAndStateLock.unlock(); + } + } + } + + public void release() { + if (isValid()) { + try { + sendAndStateLock.lock(); + super.release(); + } catch (Exception e) { + logger.debug("Failed to release session", e); + } finally { + sendAndStateLock.unlock(); + } + } else { + logger.debug("Trying to release an already invalid session, with Session ID '{}'", getSessionId()); + } + } + + private class RequestDelivery implements Runnable { + ServerSLhSession session; + Request request; + + public void run() { + try { + switch (request.getCommandCode()) { + case LCSRoutingInfoRequest.code: + handleEvent( + new Event(Event.Type.RECEIVE_RIR, messageFactory.createLCSRoutingInfoRequest(request), null)); + break; + + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), null); + break; + } + } catch (Exception e) { + logger.debug("Failed to process request message", e); + } + } + } + + private class AnswerDelivery implements Runnable { + ServerSLhSession session; + Answer answer; + Request request; + + public void run() { + try { + switch (answer.getCommandCode()) { + default: + listener.doOtherEvent(session, new AppRequestEventImpl(request), new AppAnswerEventImpl(answer)); + break; + } + } catch (Exception e) { + logger.debug("Failed to process success message", e); + } + } + } + +} \ No newline at end of file diff --git a/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/ServerSLhSessionDataLocalImpl.java b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/ServerSLhSessionDataLocalImpl.java new file mode 100644 index 000000000..3e1914e9e --- /dev/null +++ b/core/jdiameter/impl/src/main/java/org/jdiameter/server/impl/app/slh/ServerSLhSessionDataLocalImpl.java @@ -0,0 +1,57 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.jdiameter.server.impl.app.slh; + +import org.jdiameter.common.impl.app.slh.SLhLocalSessionDataImpl; + +/** + * @author Fernando Mendioroz + * + */ + +public class ServerSLhSessionDataLocalImpl extends SLhLocalSessionDataImpl implements IServerSLhSessionData { + + public ServerSLhSessionDataLocalImpl() { + } + +} \ No newline at end of file diff --git a/core/mux/common/config/dictionary.xml b/core/mux/common/config/dictionary.xml index 6f7c02bc2..6aac1b8f1 100644 --- a/core/mux/common/config/dictionary.xml +++ b/core/mux/common/config/dictionary.xml @@ -7867,4 +7867,637 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractDeferredClient.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractDeferredClient.java new file mode 100644 index 000000000..7dab8906b --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractDeferredClient.java @@ -0,0 +1,530 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg; + +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpSet; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.Mode; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ClientSLgSessionListener; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.slg.LocationReportRequestImpl; +import org.jdiameter.common.impl.app.slg.SLgSessionFactoryImpl; +import org.mobicents.diameter.stack.functional.TBase; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class AbstractDeferredClient extends TBase implements ClientSLgSessionListener { + + // NOTE: implementing NetworkReqListener since its required for stack to + // know we support it... ech. + + protected ClientSLgSession clientSLgSession; + + public void init(InputStream configStream, String clientID) throws Exception { + try { + super.init(configStream, clientID, ApplicationId.createByAuthAppId(10415, 16777255)); + SLgSessionFactoryImpl sLgSessionFactory = new SLgSessionFactoryImpl(this.sessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLgSession.class, sLgSessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLgSession.class, sLgSessionFactory); + + sLgSessionFactory .setClientSessionListener(this); + + this.clientSLgSession = ((ISessionFactory) this.sessionFactory).getNewAppSession(this.sessionFactory.getSessionId("xx-SLg-TESTxx"), getApplicationId(), + ClientSLgSession.class, null); + } finally { + try { + configStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // ----------- delegate methods so + + public void start() throws IllegalDiameterStateException, InternalException { + stack.start(); + } + + public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { + stack.start(mode, timeOut, timeUnit); + } + + public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { + stack.stop(timeOut, timeUnit, disconnectCause); + } + + public void stop(int disconnectCause) { + stack.stop(disconnectCause); + } + + // ------- def methods, to fail :) + + public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"Other\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doLocationReportAnswerEvent(ClientSLgSession session, LocationReportRequest request, LocationReportAnswer answer) throws InternalException, + IllegalDiameterStateException, RouteException, OverloadException { + fail("Received \"LRA\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doProvideLocationAnswerEvent(ClientSLgSession session, ProvideLocationRequest request, ProvideLocationAnswer answer) throws InternalException, + IllegalDiameterStateException, RouteException, OverloadException { + fail("Received \"PLA\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + // ----------- conf parts + + public String getSessionId() { + return this.clientSLgSession.getSessionId(); + } + + public ClientSLgSession getSession() { + return this.clientSLgSession; + } + + // Attributes for Location Report Request (LRR) + protected abstract String getUserName(); // IE: IMSI + protected abstract byte[] getMSISDN(); + protected abstract String getIMEI(); + protected abstract String getLCSNameString(); + protected abstract int getLCSFormatIndicator(); + protected abstract int getLCSQoSClass(); + protected abstract long getLSCServiceTypeId(); + protected abstract long getDeferredLocationType(); + protected abstract byte[] getLCSReferenceNumber(); + protected abstract java.net.InetAddress getGMLCAddress(); + protected abstract long getReportingAmount(); + protected abstract long getReportingInterval(); + protected abstract int getLocationEvent(); + protected abstract byte[] getLocationEstimate(); + protected abstract int getAccuracyFulfilmentIndicator(); + protected abstract long getAgeOfLocationEstimate(); + protected abstract byte[] getVelocityEstimate(); + protected abstract byte[] getEUTRANPositioningData(); + protected abstract byte[] getECGI(); + protected abstract byte[] getGERANPositioningData(); + protected abstract byte[] getGERANGANSSPositioningData(); + protected abstract byte[] getCellGlobalIdentity(); + protected abstract byte[] getUTRANPositioningData(); + protected abstract byte[] getUTRANGANSSPositioningData(); + protected abstract byte[] getServiceAreaIdentity(); + protected abstract int getPseudonymIndicator(); + protected abstract byte[] getSGSNNumber(); + protected abstract String getSGSNName(); + protected abstract String getSGSNRealm(); + protected abstract String getMMEName(); + protected abstract String getMMERealm(); + protected abstract byte[] getMSCNumber(); + protected abstract String get3GPPAAAServerName(); + protected abstract long getLCSCapabilitiesSets(); + protected abstract long getLRRFLags(); + protected abstract long getTerminationCause(); + protected abstract long getCellPortionId(); + protected abstract byte[] get1xRTTRCID(); + protected abstract String getCivicAddress(); + protected abstract long getBarometricPressure(); + + // ----------- 3GPP TS 29.172 reference + + protected LocationReportRequest createLRR(ClientSLgSession slgSession) throws Exception { + /* + < Location-Report-Request> ::= < Diameter Header: 8388621, REQ, PXY, 16777255 > + + < Session-Id > + [ Vendor-Specific-Application-Id ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + { Destination-Host } + { Destination-Realm } + { Location-Event } + [ LCS-EPS-Client-Name ] + [ User-Name ] + [ MSISDN] + [ IMEI ] + [ Location-Estimate ] + [ Accuracy-Fulfilment-Indicator ] + [ Age-Of-Location-Estimate ] + [ Velocity-Estimate ] + [ EUTRAN-Positioning-Data ] + [ ECGI ] + [ GERAN-Positioning-Info ] + [ Cell-Global-Identity ] + [ UTRAN-Positioning-Info ] + [ Service-Area-Identity ] + [ LCS-Service-Type-ID ] + [ Pseudonym-Indicator ] + [ LCS-QoS-Class ] + [ Serving-Node ] + [ LRR-Flags ] + [ LCS-Reference-Number ] + [ Deferred-MT-LR-Data] + [ GMLC-Address ] + [ Periodic-LDR-Information ] + [ ESMLC-Cell-Info ] + [ 1xRTT-RCID ] + [ Civic-Address ] + [ Barometric-Pressure ] + *[ Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + + */ + // Create LocationReportRequest + LocationReportRequest lrr = new LocationReportRequestImpl(slgSession.getSessions().get(0).createRequest(LocationReportRequest.code, getApplicationId(), + getServerRealmName())); + // < Location-Report-Request> ::= < Diameter Header: 8388621, REQ, PXY, 16777255 > + + AvpSet reqSet = lrr.getMessage().getAvps(); + + if (reqSet.getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { + AvpSet vendorSpecificApplicationId = reqSet.addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, 0, false, false); + // 1* [ Vendor-Id ] + vendorSpecificApplicationId.addAvp(Avp.VENDOR_ID, getApplicationId().getVendorId(), true); + // 0*1{ Auth-Application-Id } + vendorSpecificApplicationId.addAvp(Avp.AUTH_APPLICATION_ID, getApplicationId().getAuthAppId(), true); + } + + // { Auth-Session-State } + if (reqSet.getAvp(Avp.AUTH_SESSION_STATE) == null) { + reqSet.addAvp(Avp.AUTH_SESSION_STATE, 1); + } + + // { Origin-Host } + reqSet.removeAvp(Avp.ORIGIN_HOST); + reqSet.addAvp(Avp.ORIGIN_HOST, getClientURI(), true); + + // { Location-Event } + int locationEvent = getLocationEvent(); + if (locationEvent != -1){ + reqSet.addAvp(Avp.LOCATION_EVENT, locationEvent, 10415, true, false); + } + + // { LCS-EPS-Client-Name } + AvpSet lcsEPSClientName = reqSet.addGroupedAvp(Avp.LCS_EPS_CLIENT_NAME, 10415, false, false); + String lcsNameString = getLCSNameString(); + int lcsFormatIndicator = getLCSFormatIndicator(); + + if (lcsNameString != null){ + lcsEPSClientName.addAvp(Avp.LCS_NAME_STRING, lcsNameString, 10415, false, false, false); + } + if (lcsFormatIndicator != -1){ + lcsEPSClientName.addAvp(Avp.LCS_FORMAT_INDICATOR, lcsFormatIndicator, 10415, false, false); + } + + // [ User-Name ] IE: IMSI + String userName = getUserName(); + if (userName != null) { + reqSet.addAvp(Avp.USER_NAME, userName, 10415, true, false, false); + } + + // [ MSISDN ] + byte[] msisdn = getMSISDN(); + if (msisdn != null){ + reqSet.addAvp(Avp.MSISDN, msisdn, 10415, true, false); + } + + // [ IMEI ] + String imei = getIMEI(); + if (imei != null){ + reqSet.addAvp(Avp.TGPP_IMEI, imei, 10415, false, false, false); + } + + // [ Location-Estimate ] + byte[] locationEstimate = getLocationEstimate(); + if (locationEstimate != null){ + reqSet.addAvp(Avp.LOCATION_ESTIMATE, locationEstimate, 10415, true, false); + } + + // [ Accuracy-Fulfilment-Indicator ] + int accuracyFulfilmentIndicator = getAccuracyFulfilmentIndicator(); + if (accuracyFulfilmentIndicator != -1){ + reqSet.addAvp(Avp.ACCURACY_FULFILMENT_INDICATOR, accuracyFulfilmentIndicator, 10415, false, false); + } + + // [ Age-Of-Location-Estimate ] + long ageOfLocationEstimate = getAgeOfLocationEstimate(); + if (ageOfLocationEstimate != -1){ + reqSet.addAvp(Avp.AGE_OF_LOCATION_ESTIMATE, ageOfLocationEstimate, 10415, false, false, true); + } + + // [ Velocity-Estimate ] + byte[] velocityEstimate = getVelocityEstimate(); + if (velocityEstimate != null){ + reqSet.addAvp(Avp.VELOCITY_ESTIMATE, velocityEstimate, 10415, false, false); + } + + // [ EUTRAN-Positioning-Data ] + byte[] eutranPositioningData = getEUTRANPositioningData(); + if (eutranPositioningData != null){ + reqSet.addAvp(Avp.EUTRAN_POSITIONING_DATA, eutranPositioningData, 10415, false, false); + } + + // [ ECGI ] + byte[] ecgi = getECGI(); + if (ecgi != null){ + reqSet.addAvp(Avp.ECGI, ecgi, 10415, false, false); + } + + // [ GERAN-Positioning-Info ] + AvpSet geranPositioningInfo = reqSet.addGroupedAvp(Avp.GERAN_POSITIONING_INFO, 10415, false, false); + byte[] geranPositioningData = getGERANPositioningData(); + byte[] geranGanssPositioningData = getGERANGANSSPositioningData(); + + if (geranPositioningData != null){ + geranPositioningInfo.addAvp(Avp.GERAN_POSITIONING_DATA, geranPositioningData, 10415, false, false); + } + if (geranGanssPositioningData != null){ + geranPositioningInfo.addAvp(Avp.GERAN_GANSS_POSITIONING_DATA, geranGanssPositioningData, 10415, false, false); + } + + // [ Cell-Global-Identity ] + byte[] cellGlobalIdentity = getCellGlobalIdentity(); + if (cellGlobalIdentity != null){ + reqSet.addAvp(Avp.CELL_GLOBAL_IDENTITY, cellGlobalIdentity, 10415, false, false); + } + + // [ UTRAN-Positioning-Info ] + AvpSet utranPositioningInfo = reqSet.addGroupedAvp(Avp.UTRAN_POSITIONING_INFO, 10415, false, false); + byte[] utranPositioningData = getUTRANPositioningData(); + byte[] utranGanssPositioningData = getUTRANGANSSPositioningData(); + + if (utranPositioningData != null){ + utranPositioningInfo.addAvp(Avp.UTRAN_POSITIONING_DATA, utranPositioningData, 10415, false, false); + } + if (utranGanssPositioningData != null){ + utranPositioningInfo.addAvp(Avp.UTRAN_GANSS_POSITIONING_DATA, utranGanssPositioningData, 10415, false, false); + } + + // [ Service-Area-Identity ] + byte[] serviceAreaIdentity = getServiceAreaIdentity(); + if (serviceAreaIdentity != null){ + reqSet.addAvp(Avp.SERVICE_AREA_IDENTITY, serviceAreaIdentity, 10415, false, false); + } + + // [ LCS-Service-Type-ID ] + long lscServiceTypeId = getLSCServiceTypeId(); + if (lscServiceTypeId != -1){ + reqSet.addAvp(Avp.LCS_SERVICE_TYPE_ID, lscServiceTypeId, 10415, false, false, true); + } + + // [ Pseudonym-Indicator ] + int pseudonymIndicator = getPseudonymIndicator(); + if (pseudonymIndicator != -1){ + reqSet.addAvp(Avp.PSEUDONYM_INDICATOR, pseudonymIndicator, 10415, false, false); + } + + // [ LCS-QoS-Class ] + int lcsQoSClass = getLCSQoSClass(); + if (lcsQoSClass != -1){ + reqSet.addAvp(Avp.LCS_QOS_CLASS, lcsQoSClass, 10415, false, false); + } + + // [ Serving-Node ] IE: Target Serving Node Identity +/* + Serving-Node ::= + [ SGSN-Number ] + [ SGSN-Name ] + [ SGSN-Realm ] + [ MME-Name ] + [ MME-Realm ] + [ MSC-Number ] + [ 3GPP-AAA-Server-Name ] + [ LCS-Capabilities-Sets ] + [ GMLC-Address ] + *[AVP] + +*/ + AvpSet servingNode = reqSet.addGroupedAvp(Avp.SERVING_NODE, 10415, true, false); + byte[] sgsnNumber = getSGSNNumber(); + String sgsnName= getSGSNName(); + String sgsnRealm = getSGSNRealm(); + String mmeName = getMMEName(); + String mmeRealm = getMMERealm(); + byte[] mscNumber = getMSCNumber(); + String tgppAAAServerName= get3GPPAAAServerName(); + long lcsCapabilitiesSet = getLCSCapabilitiesSets(); + java.net.InetAddress gmlcAddress = getGMLCAddress(); + + if (sgsnNumber != null){ + servingNode.addAvp(Avp.SGSN_NUMBER, sgsnNumber, 10415, false, false); + } + if (sgsnName != null){ + servingNode.addAvp(Avp.SGSN_NAME, sgsnName, 10415, false, false, false); + } + if (sgsnRealm != null){ + servingNode.addAvp(Avp.SGSN_REALM, sgsnRealm, 10415, false, false, false); + } + if (mmeName != null){ + servingNode.addAvp(Avp.MME_NAME, mmeName, 10415, false, false, false); + } + if (mmeRealm != null){ + servingNode.addAvp(Avp.MME_REALM, mmeRealm, 10415, false, false, false); + } + if (mscNumber != null){ + servingNode.addAvp(Avp.MSC_NUMBER, mscNumber, 10415, false, false); + } + if (tgppAAAServerName != null){ + servingNode.addAvp(Avp.TGPP_AAA_SERVER_NAME, tgppAAAServerName, 10415, false, false, false); + } + if (lcsCapabilitiesSet != -1){ + servingNode.addAvp(Avp.LCS_CAPABILITIES_SETS, lcsCapabilitiesSet, 10415, false, false, true); + } + if (gmlcAddress != null){ + servingNode.addAvp(Avp.GMLC_ADDRESS, gmlcAddress, 10415, false, false); + } + + // [ LRR-Flags ] + long lrrFlags = getLRRFLags(); + if (lrrFlags != -1){ + reqSet.addAvp(Avp.LRR_FLAGS, lrrFlags, 10415, false, false, true); + } + + // [ LCS-Reference-Number ] + byte[] lcsReferenceNumber = getLCSReferenceNumber(); + if (lcsReferenceNumber != null){ + reqSet.addAvp(Avp.LCS_REFERENCE_NUMBER, lcsReferenceNumber, 10415, true, false); + } + + // [ Deferred-MT-LR-Data] + AvpSet deferredMTLRData = reqSet.addGroupedAvp(Avp.DEFERRED_MT_LR_DATA, 10415, false, false); + long deferredLocationType = getDeferredLocationType(); + long terminationCause = getTerminationCause(); + + if (deferredLocationType != -1){ + deferredMTLRData.addAvp(Avp.DEFERRED_LOCATION_TYPE, deferredLocationType, 10415, false, false, true); + } + if (terminationCause != -1){ + deferredMTLRData.addAvp(Avp.TERMINATION_CAUSE_LCS, terminationCause, 10415, false, false, true); + } + + // [ GMLC-Address ] + // attribute already defined for grouped AVP Serving Node + if (gmlcAddress != null){ + reqSet.addAvp(Avp.GMLC_ADDRESS, gmlcAddress, 10415, false, false); + } + + //[ Periodic-LDR-Information ] +/* +Periodic-LDR-Info ::= + { Reporting-Amount } + { Reporting-Interval } + *[ AVP ] +Reporting-Interval x Rreporting-Amount shall not exceed 8639999 (99 days, 23 hours, 59 minutes and 59 seconds) +for compatibility with OMA MLP and RLP. +*/ + AvpSet periodicLDRInfo = reqSet.addGroupedAvp(Avp.PERIODIC_LDR_INFORMATION, 10415, false, false); + long reportingAmount = getReportingAmount(); + long reportingInterval = getReportingInterval(); + + if (reportingAmount != -1){ + periodicLDRInfo.addAvp(Avp.REPORTING_AMOUNT, reportingAmount, 10415, false, false, true); + } + if (reportingInterval != -1){ + periodicLDRInfo.addAvp(Avp.REPORTING_INTERVAL, reportingInterval, 10415, false, false, true); + } + + // [ ESMLC-Cell-Info ] +/* + ESMLC-Cell-Info ::= + [ ECGI ] + [ Cell-Portion-ID ] + *[ AVP ] +*/ + AvpSet esmlcCellInfo = reqSet.addGroupedAvp(Avp.ESMLC_CELL_INFO, 10415, false, false); + // ECGI attribute already defined + long cellPortionId = getCellPortionId(); + + if (ecgi != null){ + esmlcCellInfo.addAvp(Avp.ECGI, ecgi, 10415, false, false); + } + if (cellPortionId != -1){ + esmlcCellInfo.addAvp(Avp.CELL_PORTION_ID, cellPortionId, 10415, false, false, true); + } + + // [ 1xRTT-RCID ] + byte[] onexRTTRCID = get1xRTTRCID(); + if (onexRTTRCID != null){ + reqSet.addAvp(Avp.ONEXRTT_RCID, onexRTTRCID, 10415, false, false); + } + + // [ Civic-Address ] + String civicAddress = getCivicAddress(); + if (civicAddress != null){ + reqSet.addAvp(Avp.CIVIC_ADDRESS, civicAddress, 10415, false, false, false); + } + + // [ Barometric-Pressure ] + long barometricPressure = getBarometricPressure(); + if (barometricPressure != -1){ + reqSet.addAvp(Avp.BAROMETRIC_PRESSURE, barometricPressure, 10415, false, false, true); + } + + return lrr; + } + +} diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractDeferredServer.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractDeferredServer.java new file mode 100644 index 000000000..d83fcf547 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractDeferredServer.java @@ -0,0 +1,247 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg; + +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpSet; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.Mode; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.ServerSLgSessionListener; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.slg.LocationReportAnswerImpl; +import org.jdiameter.common.impl.app.slg.SLgSessionFactoryImpl; +import org.mobicents.diameter.stack.functional.TBase; + +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class AbstractDeferredServer extends TBase implements ServerSLgSessionListener { + + // NOTE: implementing NetworkReqListener since its required for stack to + // know we support it... ech. + + protected ServerSLgSession serverSLgSession; + + public void init(InputStream configStream, String clientID) throws Exception { + try { + super.init(configStream, clientID, ApplicationId.createByAuthAppId(10415, 16777255)); + SLgSessionFactoryImpl slgSessionFactory = new SLgSessionFactoryImpl(this.sessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLgSession.class, slgSessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLgSession.class, slgSessionFactory); + slgSessionFactory.setServerSessionListener(this); + } finally { + try { + configStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // ----------- delegate methods so + + public void start() throws IllegalDiameterStateException, InternalException { + stack.start(); + } + + public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { + stack.start(mode, timeOut, timeUnit); + } + + public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { + stack.stop(timeOut, timeUnit, disconnectCause); + } + + public void stop(int disconnectCause) { + stack.stop(disconnectCause); + } + + public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, + RouteException, + OverloadException { + fail("Received \"Other\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doLocationReportRequestEvent(ServerSLgSession session, LocationReportRequest request) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"LRR\" event, request[" + request + "], on session[" + session + "]", null); + } + // -------- conf + + public String getSessionId() { + return this.serverSLgSession.getSessionId(); + } + + public void fetchSession(String sessionId) throws InternalException { + this.serverSLgSession = stack.getSession(sessionId, ServerSLgSession.class); + } + + public ServerSLgSession getSession() { + return this.serverSLgSession; + } + + // Attributes for Location Report Answer (LRA) + protected abstract java.net.InetAddress getGMLCAddress(); + protected abstract long getLRAFLags(); + protected abstract int getPrioritizedListIndicator(); + protected abstract byte[] getVisitedPLMNId(); + protected abstract int getPeriodicLocationSupportIndicator(); + protected abstract byte[] getLCSReferenceNumber(); + + // ----------- 3GPP TS 29.172 reference + + public LocationReportAnswer createLRA(LocationReportRequest lrr, long resultCode) throws Exception { + /* + < Location-Report-Answer > ::= < Diameter Header: 8388621, PXY, 16777255> + + < Session-Id > + [ Vendor-Specific-Application-Id ] + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ GMLC-Address ] + [ LRA-Flags ] + [ Reporting-PLMN-List ] + [ LCS-Reference-Number ] + *[ Supported-Features ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + + */ + LocationReportAnswer lra = new LocationReportAnswerImpl((Request) lrr.getMessage(), resultCode); + + AvpSet reqSet = lrr.getMessage().getAvps(); + AvpSet set = lra.getMessage().getAvps(); + set.removeAvp(Avp.DESTINATION_HOST); + set.removeAvp(Avp.DESTINATION_REALM); + set.addAvp(reqSet.getAvp(Avp.AUTH_APPLICATION_ID)); + + // { Vendor-Specific-Application-Id } + if (set.getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { + AvpSet vendorSpecificApplicationId = set.addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, 0, false, false); + // 1* [ Vendor-Id ] + vendorSpecificApplicationId.addAvp(Avp.VENDOR_ID, getApplicationId().getVendorId(), true); + // 0*1{ Auth-Application-Id } + vendorSpecificApplicationId.addAvp(Avp.AUTH_APPLICATION_ID, getApplicationId().getAuthAppId(), true); + } + // [ Result-Code ] + // [ Experimental-Result ] + // { Auth-Session-State } + if (set.getAvp(Avp.AUTH_SESSION_STATE) == null) { + set.addAvp(Avp.AUTH_SESSION_STATE, 1); + } + + //[ GMLC-Address ] + java.net.InetAddress gmlcAddress = getGMLCAddress(); + if (gmlcAddress != null){ + set.addAvp(Avp.GMLC_ADDRESS, gmlcAddress, 10415, false, false); + } + + // [ LRA-Flags ] + long lraFlags = getLRAFLags(); + if (lraFlags != -1){ + set.addAvp(Avp.LRA_FLAGS, lraFlags, 10415, false, false, true); + } + + //[ Reporting-PLMN-List ] +/* + Reporting-PLMN-List ::= + 1*20{ PLMN-ID-List } + [ Prioritized-List-Indicator ] + *[ AVP ] + + PLMN-ID-List ::= + { Visited-PLMN-Id } + [ Periodic-Location-Support-Indicator ] + *[ AVP ] +*/ + AvpSet reportingPLMNList = set.addGroupedAvp(Avp.REPORTING_PLMN_LIST, 10415, false, false); + int prioritizedListIndicator = getPrioritizedListIndicator(); + AvpSet plmnIdList = set.addGroupedAvp(Avp.PLMN_ID_LIST, 10415, false, false); + byte[] visitedPLMNId = getVisitedPLMNId(); + int periodicLocationSupportIndicator = getPeriodicLocationSupportIndicator(); + + if (prioritizedListIndicator != -1){ + reportingPLMNList.addAvp(Avp.PRIORITIZED_LIST_INDICATOR, prioritizedListIndicator, 10415, false, false); + } + if (plmnIdList != null){ + reportingPLMNList.addAvp(plmnIdList); + } + if (visitedPLMNId != null){ + plmnIdList.addAvp(Avp.VISITED_PLMN_ID, visitedPLMNId, 10415, false, false); + } + if (periodicLocationSupportIndicator != -1){ + plmnIdList.addAvp(Avp.PERIODIC_LOCATION_SUPPORT_INDICATOR, periodicLocationSupportIndicator, 10415, false, false); + } + + // [ LCS-Reference-Number ] + byte[] lcsReferenceNumber = getLCSReferenceNumber(); + if (lcsReferenceNumber != null){ + set.addAvp(Avp.LCS_REFERENCE_NUMBER, lcsReferenceNumber, 10415, true, false); + } + + return lra; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractImmediateClient.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractImmediateClient.java new file mode 100644 index 000000000..1ff3b5afb --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractImmediateClient.java @@ -0,0 +1,472 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg; + +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpSet; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.Mode; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ClientSLgSessionListener; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.slg.ProvideLocationRequestImpl; +import org.jdiameter.common.impl.app.slg.SLgSessionFactoryImpl; +import org.mobicents.diameter.stack.functional.TBase; + +/** + * + *@author Fernando Mendioroz + * + */ +public abstract class AbstractImmediateClient extends TBase implements ClientSLgSessionListener { + + // NOTE: implementing NetworkReqListener since its required for stack to + // know we support it... ech. + + protected ClientSLgSession clientSLgSession; + + public void init(InputStream configStream, String clientID) throws Exception { + try { + super.init(configStream, clientID, ApplicationId.createByAuthAppId(10415, 16777255)); + SLgSessionFactoryImpl sLgSessionFactory = new SLgSessionFactoryImpl(this.sessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLgSession.class, sLgSessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLgSession.class, sLgSessionFactory); + + sLgSessionFactory .setClientSessionListener(this); + + this.clientSLgSession = ((ISessionFactory) this.sessionFactory).getNewAppSession(this.sessionFactory.getSessionId("xx-SLg-TESTxx"), getApplicationId(), + ClientSLgSession.class, null); + } finally { + try { + configStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // ----------- delegate methods so + + public void start() throws IllegalDiameterStateException, InternalException { + stack.start(); + } + + public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { + stack.start(mode, timeOut, timeUnit); + } + + public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { + stack.stop(timeOut, timeUnit, disconnectCause); + } + + public void stop(int disconnectCause) { + stack.stop(disconnectCause); + } + + // ------- def methods, to fail :) + + public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"Other\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doProvideLocationAnswerEvent(ClientSLgSession session, ProvideLocationRequest request, ProvideLocationAnswer answer) throws InternalException, + IllegalDiameterStateException, RouteException, OverloadException { + fail("Received \"PLA\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doLocationReportAnswerEvent(ClientSLgSession session, LocationReportRequest request, LocationReportAnswer answer) throws InternalException, + IllegalDiameterStateException, RouteException, OverloadException { + fail("Received \"LRA\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + // ----------- conf parts + + public String getSessionId() { + return this.clientSLgSession.getSessionId(); + } + + public ClientSLgSession getSession() { + return this.clientSLgSession; + } + + // Attributes for Provide Location Request (PLR) + protected abstract int getSLgLocationType(); + protected abstract String getUserName(); // IE: IMSI + protected abstract byte[] getMSISDN(); + protected abstract String getIMEI(); + protected abstract String getLCSNameString(); + protected abstract int getLCSFormatIndicator(); + protected abstract int getLCSClientType(); + protected abstract String getLCSRequestorIdString(); + protected abstract int getReqLCSFormatIndicator(); + protected abstract long getLCSPriority(); + protected abstract int getLCSQoSClass(); + protected abstract long getHorizontalAccuracy(); + protected abstract long getVerticalAccuracy(); + protected abstract int getVerticalRequested(); + protected abstract int getResponseTime(); + protected abstract int getVelocityRequested(); + protected abstract long getSupportedGADShapes(); + protected abstract long getLSCServiceTypeId(); + protected abstract String getLCSCodeword(); + protected abstract String getServiceSelection(); // IE: APN + protected abstract int getLCSPrivacyCheckSession(); + protected abstract int getLCSPrivacyCheckNonSession(); + protected abstract long getDeferredLocationType(); + protected abstract byte[] getLCSReferenceNumber(); + protected abstract int getOccurrenceInfo(); + protected abstract long getIntervalTime(); + protected abstract long getAreaType(); + protected abstract byte[] getAreaIdentification(); + protected abstract java.net.InetAddress getGMLCAddress(); + protected abstract long getPLRFLags(); + protected abstract long getReportingAmount(); + protected abstract long getReportingInterval(); + protected abstract int getPrioritizedListIndicator(); + protected abstract byte[] getVisitedPLMNId(); + protected abstract int getPeriodicLocationSupportIndicator(); + + // ----------- 3GPP TS 29.172 reference + + protected ProvideLocationRequest createPLR(ClientSLgSession slgSession) throws Exception { + /* + < Provide-Location-Request> ::= < Diameter Header: 8388620, REQ, PXY, 16777255 > + + < Session-Id > + [ Vendor-Specific-Application-Id ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + { Destination-Host } + { Destination-Realm } + { SLg-Location-Type } + [ User-Name ] + [ MSISDN ] + [ IMEI ] + { LCS-EPS-Client-Name } + { LCS-Client-Type } + [ LCS-Requestor-Name ] + [ LCS-Priority ] + [ LCS-QoS ] + [ Velocity-Requested ] + [ LCS-Supported-GAD-Shapes ] + [ LCS-Service-Type-ID ] + [ LCS-Codeword ] + [ LCS-Privacy-Check-Non-Session ] + [ LCS-Privacy-Check-Session ] + [ Service-Selection ] + [ Deferred-Location-Type ] + [ PLR-Flags ] + *[ Supported-Features ] + *[ AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + Note: plus all extra AVPs defined in Table 6.2.2-1: Provide Subscriber Location Request, i.e. + [ LCS-Reference-Number ] + [ Area-Event-Info ] + [ GMLC-Address ] + [ Periodic-LDR-Information ] + [ Reporting-PLMN-List ] + */ + // Create ProvideLocationRequest + ProvideLocationRequest plr = new ProvideLocationRequestImpl(slgSession.getSessions().get(0).createRequest(ProvideLocationRequest.code, getApplicationId(), + getServerRealmName())); + // < Provide-Location-Request> ::= < Diameter Header: 8388620, REQ, PXY, 16777255 > + + AvpSet reqSet = plr.getMessage().getAvps(); + + if (reqSet.getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { + AvpSet vendorSpecificApplicationId = reqSet.addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, 0, false, false); + // 1* [ Vendor-Id ] + vendorSpecificApplicationId.addAvp(Avp.VENDOR_ID, getApplicationId().getVendorId(), true); + // 0*1{ Auth-Application-Id } + vendorSpecificApplicationId.addAvp(Avp.AUTH_APPLICATION_ID, getApplicationId().getAuthAppId(), true); + } + + // { Auth-Session-State } + if (reqSet.getAvp(Avp.AUTH_SESSION_STATE) == null) { + reqSet.addAvp(Avp.AUTH_SESSION_STATE, 1); + } + + // { Origin-Host } + reqSet.removeAvp(Avp.ORIGIN_HOST); + reqSet.addAvp(Avp.ORIGIN_HOST, getClientURI(), true); + + + // { SLg-Location-Type } + int slgLocationType = getSLgLocationType(); + if (slgLocationType != -1){ + reqSet.addAvp(Avp.SLG_LOCATION_TYPE, slgLocationType, 10415, true, false); + } + + // [ User-Name ] IE: IMSI + String userName = getUserName(); + if (userName != null) { + reqSet.addAvp(Avp.USER_NAME, userName, 10415, true, false, false); + } + + // [ MSISDN ] + byte[] msisdn = getMSISDN(); + if (msisdn != null){ + reqSet.addAvp(Avp.MSISDN, msisdn, 10415, true, false); + } + + // [ IMEI ] + String imei = getIMEI(); + if (imei != null){ + reqSet.addAvp(Avp.TGPP_IMEI, imei, 10415, false, false, false); + } + + // { LCS-EPS-Client-Name } + AvpSet lcsEPSClientName = reqSet.addGroupedAvp(Avp.LCS_EPS_CLIENT_NAME, 10415, false, false); + String lcsNameString = getLCSNameString(); + int lcsFormatIndicator = getLCSFormatIndicator(); + + if (lcsNameString != null){ + lcsEPSClientName.addAvp(Avp.LCS_NAME_STRING, lcsNameString, 10415, false, false, false); + } + if (lcsFormatIndicator != -1){ + lcsEPSClientName.addAvp(Avp.LCS_FORMAT_INDICATOR, lcsFormatIndicator, 10415, false, false); + } + + // { LCS-Client-Type } + int lcsClientType = getLCSClientType(); + if (lcsClientType != -1){ + reqSet.addAvp(Avp.LCS_CLIENT_TYPE, lcsClientType, 10415, false, false); + } + + // [ LCS-Requestor-Name ] + AvpSet lcsRequestorName = reqSet.addGroupedAvp(Avp.LCS_REQUESTOR_NAME, 10415, false, false); + String lcsRequestorIdString = getLCSRequestorIdString(); + int reqLCSFormatIndicator = getReqLCSFormatIndicator(); + + if (lcsRequestorIdString != null){ + lcsRequestorName.addAvp(Avp.LCS_REQUESTOR_ID_STRING, lcsRequestorIdString, 10415, false, false, false); + } + if (reqLCSFormatIndicator != -1){ + lcsRequestorName.addAvp(Avp.LCS_FORMAT_INDICATOR, reqLCSFormatIndicator, 10415, false, false); + } + + // [ LCS-Priority ] + long lcsPriority = getLCSPriority(); + if (lcsPriority != -1){ + reqSet.addAvp(Avp.LCS_PRIORITY, lcsPriority, 10415, false, false, true); + } + + // [ LCS-QoS ] + AvpSet lcsQoS = reqSet.addGroupedAvp(Avp.LCS_QOS, 10415, false, false); + int lcsQoSClass = getLCSQoSClass(); + long horizontalAccuracy = getHorizontalAccuracy(); + long verticalAccuracy = getVerticalAccuracy(); + int verticalRequested = getVerticalRequested(); + int responseTime = getResponseTime(); + + if (lcsQoSClass != -1){ + lcsQoS.addAvp(Avp.LCS_QOS_CLASS, lcsQoSClass, 10415, false, false); + } + if (horizontalAccuracy != -1){ + lcsQoS.addAvp(Avp.HORIZONTAL_ACCURACY, horizontalAccuracy, 10415, false, false, true); + } + if(verticalAccuracy != -1){ + lcsQoS.addAvp(Avp.VERTICAL_ACCURACY, verticalAccuracy, 10415, false, false, true); + } + if(verticalRequested != -1){ + lcsQoS.addAvp(Avp.VERTICAL_REQUESTED, verticalRequested, 10415, false, false); + } + if(responseTime != -1){ + lcsQoS.addAvp(Avp.RESPONSE_TIME, responseTime, 10415, false, false); + } + + // [ Velocity-Requested ] + int velocityRequested = getVelocityRequested(); + if (velocityRequested != -1){ + reqSet.addAvp(Avp.VELOCITY_REQUESTED, velocityRequested, 10415, false, false); + } + + // [ LCS-Supported-GAD-Shapes ] + long supportedGADShapes = getSupportedGADShapes(); + if (supportedGADShapes != -1){ + reqSet.addAvp(Avp.SUPPORTED_GAD_SHAPES, supportedGADShapes, 10415, false, false, true); + } + + // [ LCS-Service-Type-ID ] + long lscServiceTypeId = getLSCServiceTypeId(); + if (lscServiceTypeId != -1){ + reqSet.addAvp(Avp.LCS_SERVICE_TYPE_ID, lscServiceTypeId, 10415, true, false, true); + } + + // [ LCS-Codeword ] + String lcsCodeword = getLCSCodeword(); + if (lcsCodeword != null){ + reqSet.addAvp(Avp.LCS_CODEWORD, lcsCodeword, 10415, false, false, false); + } + + //[ Service-Selection ] + String serviceSelection = getServiceSelection(); // IE: APN + if (serviceSelection != null){ + reqSet.addAvp(Avp.SERVICE_SELECTION, serviceSelection, false, false, false); + } + + // [ LCS-Privacy-Check-Session ] // IE: Session-Related Privacy Check + AvpSet lcsPrivacyCheckSession = reqSet.addGroupedAvp(Avp.LCS_PRIVACY_CHECK_SESSION, 10415, false, false); + int lcsPrivacyCheck = getLCSPrivacyCheckSession(); + + if (lcsPrivacyCheck != -1){ + lcsPrivacyCheckSession.addAvp(Avp.LCS_PRIVACY_CHECK, lcsPrivacyCheck, 10415, false, false); + } + + // [ LCS-Privacy-Check-Non-Session ] // IE: Non-Session-Related Privacy Check + AvpSet lcsPrivacyCheckNonSession = reqSet.addGroupedAvp(Avp.LCS_PRIVACY_CHECK_SESSION, 10415, false, false); + int lcsPrivacyCheckNS = getLCSPrivacyCheckNonSession(); + + if (lcsPrivacyCheckNS != -1){ + lcsPrivacyCheckNonSession.addAvp(Avp.LCS_PRIVACY_CHECK, lcsPrivacyCheck, 10415, false, false); + } + + // [ Deferred-Location-Type ] + long deferredLocationType = getDeferredLocationType(); + if (deferredLocationType != -1){ + reqSet.addAvp(Avp.DEFERRED_LOCATION_TYPE, deferredLocationType, 10415, false, false, true); + } + + // [ LCS-Reference-Number ] + byte[] lcsReferenceNumber = getLCSReferenceNumber(); + if (lcsReferenceNumber != null){ + reqSet.addAvp(Avp.LCS_REFERENCE_NUMBER, lcsReferenceNumber, 10415, true, false); + } + + // [ Area-Event-Info ] +/* + Area-Event-Info AVP of type grouped, includes: + Area-Definition, Occurrence-Info, Interval-Time + Area-Definition AVP of type grouped, includes: + Area-Type, Area-Identification +*/ + AvpSet areaEventInfo = reqSet.addGroupedAvp(Avp.AREA_EVENT_INFO, 10415, false, false); + int occurrenceInfo = getOccurrenceInfo(); + long intervalTime = getIntervalTime(); + AvpSet areaDefinition =reqSet.addGroupedAvp(Avp.AREA_DEFINITION, 10415, false, false); + long areaType = getAreaType(); + byte[] areaIdentification = getAreaIdentification(); + + if (occurrenceInfo != -1){ + areaEventInfo.addAvp(Avp.OCCURRENCE_INFO, occurrenceInfo, 10415, false, false); + } + if (intervalTime != -1){ + areaEventInfo.addAvp(Avp.INTERVAL_TIME, intervalTime, 10415, false, false, true); + } + if (areaDefinition != null){ + areaEventInfo.addAvp(areaDefinition); + } + if (areaType != -1){ + areaDefinition.addAvp(Avp.AREA_TYPE, areaType, 10415, false, false, true); + } + if (areaIdentification != null){ + areaDefinition.addAvp(Avp.AREA_IDENTIFICATION, areaIdentification, 10415, false, false); + } + + + //[ GMLC-Address ] + java.net.InetAddress gmlcAddress = getGMLCAddress(); + if (gmlcAddress != null){ + reqSet.addAvp(Avp.GMLC_ADDRESS, gmlcAddress, 10415, false, false); + } + + //[ PLR-Flags ] + long plrfLags = getPLRFLags(); + if (plrfLags != -1){ + reqSet.addAvp(Avp.PLR_FLAGS, plrfLags, 10415, false, false, true); + } + + // [ Periodic-LDR-Information ] + AvpSet periodicLDRInformation = reqSet.addGroupedAvp(Avp.AREA_EVENT_INFO, 10415, false, false); + long reportingAmount = getReportingAmount(); + long reportingInterval = getReportingInterval(); + + if (reportingAmount != -1){ + periodicLDRInformation.addAvp(Avp.REPORTING_AMOUNT, reportingAmount, 10415, false, false, true); + } + if (reportingInterval != -1){ + periodicLDRInformation.addAvp(Avp.REPORTING_INTERVAL, reportingInterval, 10415, false, false, true); + } + + // [ Reporting-PLMN-List ] + AvpSet reportingPLMNList = reqSet.addGroupedAvp(Avp.REPORTING_PLMN_LIST, 10415, false, false); + int prioritizedListIndicator = getPrioritizedListIndicator(); + AvpSet plmnIdList = reqSet.addGroupedAvp(Avp.PLMN_ID_LIST, 10415, false, false); + byte[] visitedPLMNId = getVisitedPLMNId(); + int periodicLocationSupportIndicator = getPeriodicLocationSupportIndicator(); + + if (prioritizedListIndicator != -1){ + reportingPLMNList.addAvp(Avp.PRIORITIZED_LIST_INDICATOR, prioritizedListIndicator, 10415, false, false); + } + if (plmnIdList != null){ + reportingPLMNList.addAvp(plmnIdList); + } + if (visitedPLMNId != null){ + plmnIdList.addAvp(Avp.VISITED_PLMN_ID, visitedPLMNId, 10415, false, false); + } + if (periodicLocationSupportIndicator != -1){ + plmnIdList.addAvp(Avp.PERIODIC_LOCATION_SUPPORT_INDICATOR, periodicLocationSupportIndicator, 10415, false, false); + } + + return plr; + } + +} diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractImmediateServer.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractImmediateServer.java new file mode 100644 index 000000000..7b7eb66b2 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/AbstractImmediateServer.java @@ -0,0 +1,388 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg; + +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpSet; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.Mode; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.ServerSLgSessionListener; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.slg.ProvideLocationAnswerImpl; +import org.jdiameter.common.impl.app.slg.SLgSessionFactoryImpl; +import org.mobicents.diameter.stack.functional.TBase; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class AbstractImmediateServer extends TBase implements ServerSLgSessionListener { + + // NOTE: implementing NetworkReqListener since its required for stack to + // know we support it... ech. + + protected ServerSLgSession serverSLgSession; + + public void init(InputStream configStream, String clientID) throws Exception { + try { + super.init(configStream, clientID, ApplicationId.createByAuthAppId(10415, 16777255)); + SLgSessionFactoryImpl slgSessionFactory = new SLgSessionFactoryImpl(this.sessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLgSession.class, slgSessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLgSession.class, slgSessionFactory); + slgSessionFactory.setServerSessionListener(this); + } finally { + try { + configStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // ----------- delegate methods so + + public void start() throws IllegalDiameterStateException, InternalException { + stack.start(); + } + + public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { + stack.start(mode, timeOut, timeUnit); + } + + public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { + stack.stop(timeOut, timeUnit, disconnectCause); + } + + public void stop(int disconnectCause) { + stack.stop(disconnectCause); + } + + public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, + RouteException, + OverloadException { + fail("Received \"Other\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doProvideLocationRequestEvent(ServerSLgSession session, ProvideLocationRequest request) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"PLR\" event, request[" + request + "], on session[" + session + "]", null); + } + // -------- conf + + public String getSessionId() { + return this.serverSLgSession.getSessionId(); + } + + public void fetchSession(String sessionId) throws InternalException { + this.serverSLgSession = stack.getSession(sessionId, ServerSLgSession.class); + } + + public ServerSLgSession getSession() { + return this.serverSLgSession; + } + + // Attributes for Provide Location Answer (PLA) + protected abstract byte[] getLocationEstimate(); + protected abstract int getAccuracyFulfilmentIndicator(); + protected abstract long getAgeOfLocationEstimate(); + protected abstract byte[] getVelocityEstimate(); + protected abstract byte[] getEUTRANPositioningData(); + protected abstract byte[] getECGI(); + protected abstract byte[] getGERANPositioningData(); + protected abstract byte[] getGERANGANSSPositioningData(); + protected abstract byte[] getCellGlobalIdentity(); + protected abstract byte[] getUTRANPositioningData(); + protected abstract byte[] getUTRANGANSSPositioningData(); + protected abstract byte[] getServiceAreaIdentity(); + protected abstract byte[] getSGSNNumber(); + protected abstract String getSGSNName(); + protected abstract String getSGSNRealm(); + protected abstract String getMMEName(); + protected abstract String getMMERealm(); + protected abstract byte[] getMSCNumber(); + protected abstract String get3GPPAAAServerName(); + protected abstract long getLCSCapabilitiesSets(); + protected abstract long getPLAFLags(); + protected abstract long getCellPortionId(); + protected abstract String getCivicAddress(); + protected abstract long getBarometricPressure(); + protected abstract java.net.InetAddress getGMLCAddress(); + + // ----------- 3GPP TS 29.172 reference + + public ProvideLocationAnswer createPLA(ProvideLocationRequest plr, long resultCode) throws Exception { + /* + < Provide-Location-Answer > ::= < Diameter Header: 8388620, PXY, 16777255 > + < Session-Id > + [ Vendor-Specific-Application-Id ] + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Location-Estimate ] + [ Accuracy-Fulfilment-Indicator ] + [ Age-Of-Location-Estimate] + [ Velocity-Estimate ] + [ EUTRAN-Positioning-Data] + [ ECGI ] + [ GERAN-Positioning-Info ] + [ Cell-Global-Identity ] + [ UTRAN-Positioning-Info ] + [ Service-Area-Identity ] + [ Serving-Node ] + [ PLA-Flags ] + [ ESMLC-Cell-Info ] + [ Civic-Address ] + [ Barometric-Pressure ] + *[ Supported-Features ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + + */ + ProvideLocationAnswer pla = new ProvideLocationAnswerImpl((Request) plr.getMessage(), resultCode); + + AvpSet reqSet = plr.getMessage().getAvps(); + AvpSet set = pla.getMessage().getAvps(); + set.removeAvp(Avp.DESTINATION_HOST); + set.removeAvp(Avp.DESTINATION_REALM); + set.addAvp(reqSet.getAvp(Avp.AUTH_APPLICATION_ID)); + + // { Vendor-Specific-Application-Id } + if (set.getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { + AvpSet vendorSpecificApplicationId = set.addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, 0, false, false); + // 1* [ Vendor-Id ] + vendorSpecificApplicationId.addAvp(Avp.VENDOR_ID, getApplicationId().getVendorId(), true); + // 0*1{ Auth-Application-Id } + vendorSpecificApplicationId.addAvp(Avp.AUTH_APPLICATION_ID, getApplicationId().getAuthAppId(), true); + } + // [ Result-Code ] + // [ Experimental-Result ] + // { Auth-Session-State } + if (set.getAvp(Avp.AUTH_SESSION_STATE) == null) { + set.addAvp(Avp.AUTH_SESSION_STATE, 1); + } + + // [ Location-Estimate ] + byte[] locationEstimate = getLocationEstimate(); + if (locationEstimate != null){ + set.addAvp(Avp.LOCATION_ESTIMATE, locationEstimate, 10415, true, false); + } + + // [ Accuracy-Fulfilment-Indicator ] + int accuracyFulfilmentIndicator = getAccuracyFulfilmentIndicator(); + if (accuracyFulfilmentIndicator != -1){ + set.addAvp(Avp.ACCURACY_FULFILMENT_INDICATOR, accuracyFulfilmentIndicator, 10415, false, false); + } + + // [ Age-Of-Location-Estimate ] + long ageOfLocationEstimate = getAgeOfLocationEstimate(); + if (ageOfLocationEstimate != -1){ + set.addAvp(Avp.AGE_OF_LOCATION_ESTIMATE, ageOfLocationEstimate, 10415, false, false, true); + } + + // [ Velocity-Estimate ] + byte[] velocityEstimate = getVelocityEstimate(); + if (velocityEstimate != null){ + set.addAvp(Avp.VELOCITY_ESTIMATE, velocityEstimate, 10415, false, false); + } + + // [ EUTRAN-Positioning-Data ] + byte[] eutranPositioningData = getEUTRANPositioningData(); + if (eutranPositioningData != null){ + set.addAvp(Avp.EUTRAN_POSITIONING_DATA, eutranPositioningData, 10415, false, false); + } + + // [ ECGI ] + byte[] ecgi = getECGI(); + if (ecgi != null){ + set.addAvp(Avp.ECGI, ecgi, 10415, false, false); + } + + // [ GERAN-Positioning-Info ] + AvpSet geranPositioningInfo = set.addGroupedAvp(Avp.GERAN_POSITIONING_INFO, 10415, false, false); + byte[] geranPositioningData = getGERANPositioningData(); + byte[] geranGanssPositioningData = getGERANGANSSPositioningData(); + + if (geranPositioningData != null){ + geranPositioningInfo.addAvp(Avp.GERAN_POSITIONING_DATA, geranPositioningData, 10415, false, false); + } + if (geranGanssPositioningData != null){ + geranPositioningInfo.addAvp(Avp.GERAN_GANSS_POSITIONING_DATA, geranGanssPositioningData, 10415, false, false); + } + + // [ Cell-Global-Identity ] + byte[] cellGlobalIdentity = getCellGlobalIdentity(); + if (cellGlobalIdentity != null){ + set.addAvp(Avp.CELL_GLOBAL_IDENTITY, cellGlobalIdentity, 10415, false, false); + } + + // [ UTRAN-Positioning-Info ] + AvpSet utranPositioningInfo = set.addGroupedAvp(Avp.UTRAN_POSITIONING_INFO, 10415, false, false); + byte[] utranPositioningData = getUTRANPositioningData(); + byte[] utranGanssPositioningData = getUTRANGANSSPositioningData(); + + if ( utranPositioningData != null){ + utranPositioningInfo.addAvp(Avp.UTRAN_POSITIONING_DATA, utranPositioningData, 10415, false, false); + } + if ( utranGanssPositioningData != null){ + utranPositioningInfo.addAvp(Avp.UTRAN_GANSS_POSITIONING_DATA, utranGanssPositioningData, 10415, false, false); + } + + // [ Service-Area-Identity ] + byte[] serviceAreaIdentity = getServiceAreaIdentity(); + if (serviceAreaIdentity != null){ + set.addAvp(Avp.SERVICE_AREA_IDENTITY, serviceAreaIdentity, 10415, false, false); + } + +// [ Serving-Node ] IE: Target Serving Node Identity +/* + Serving-Node ::= + [ SGSN-Number ] + [ SGSN-Name ] + [ SGSN-Realm ] + [ MME-Name ] + [ MME-Realm ] + [ MSC-Number ] + [ 3GPP-AAA-Server-Name ] + [ LCS-Capabilities-Sets ] + [ GMLC-Address ] + *[AVP] +*/ + AvpSet servingNode = set.addGroupedAvp(Avp.SERVING_NODE, 10415, false, false); + byte[] sgsnNumber = getSGSNNumber(); + String sgsnName= getSGSNName(); + String sgsnRealm = getSGSNRealm(); + String mmeName = getMMEName(); + String mmeRealm = getMMERealm(); + byte[] mscNumber = getMSCNumber(); + String tgppAAAServerName= get3GPPAAAServerName(); + long lcsCapabilitiesSet = getLCSCapabilitiesSets(); + java.net.InetAddress gmlcAddress = getGMLCAddress(); + + if (sgsnNumber != null){ + servingNode.addAvp(Avp.SGSN_NUMBER, sgsnNumber, 10415, false, false); + } + if (sgsnName != null){ + servingNode.addAvp(Avp.SGSN_NAME, sgsnName, 10415, false, false, false); + } + if (sgsnRealm != null){ + servingNode.addAvp(Avp.SGSN_REALM, sgsnRealm, 10415, false, false, false); + } + if (mmeName != null){ + servingNode.addAvp(Avp.MME_NAME, mmeName, 10415, false, false, false); + } + if (mmeRealm != null){ + servingNode.addAvp(Avp.MME_REALM, mmeRealm, 10415, false, false, false); + } + if (mscNumber != null){ + servingNode.addAvp(Avp.MSC_NUMBER, mscNumber, 10415, false, false); + } + if (tgppAAAServerName != null){ + servingNode.addAvp(Avp.TGPP_AAA_SERVER_NAME, tgppAAAServerName, 10415, false, false, false); + } + if (lcsCapabilitiesSet != -1){ + servingNode.addAvp(Avp.LCS_CAPABILITIES_SETS, lcsCapabilitiesSet, 10415, false, false, true); + } + if (gmlcAddress != null){ + servingNode.addAvp(Avp.GMLC_ADDRESS, gmlcAddress, 10415, false, false); + } + + // [ PLA-Flags ] + long plaFlags = getPLAFLags(); + if (plaFlags != -1){ + set.addAvp(Avp.PLA_FLAGS, plaFlags, 10415, false, false, true); + } + + // [ ESMLC-Cell-Info ] +/* + ESMLC-Cell-Info ::= + [ ECGI ] + [ Cell-Portion-ID ] + *[ AVP ] +*/ + AvpSet esmlcCellInfo = set.addGroupedAvp(Avp.ESMLC_CELL_INFO, 10415, false, false); + // ECGI attribute already defined + long cellPortionId = getCellPortionId(); + + if (ecgi != null){ + esmlcCellInfo.addAvp(Avp.ECGI, ecgi, 10415, false, false); + } + if (cellPortionId != -1){ + esmlcCellInfo.addAvp(Avp.CELL_PORTION_ID, cellPortionId, 10415, false, false, true); + } + + // [ Civic-Address ] + String civicAddress = getCivicAddress(); + if (civicAddress != null){ + set.addAvp(Avp.CIVIC_ADDRESS, civicAddress, 10415, false, false, false); + } + + // [ Barometric-Pressure ] + long barometricPressure = getBarometricPressure(); + if (barometricPressure != -1){ + set.addAvp(Avp.BAROMETRIC_PRESSURE, barometricPressure, 10415, false, false, true); + } + + return pla; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ClientLRR.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ClientLRR.java new file mode 100644 index 000000000..c1089ccfa --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ClientLRR.java @@ -0,0 +1,528 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg.base; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.mobicents.diameter.stack.functional.Utils; +import org.mobicents.diameter.stack.functional.slg.AbstractDeferredClient; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ClientLRR extends AbstractDeferredClient { + + protected boolean receivedLRA; + protected boolean sentLRR; + + public ClientLRR() { + } + + public void sendLocationReportRequest() throws Exception { + LocationReportRequest lrr = super.createLRR(super.clientSLgSession); + super.clientSLgSession.sendLocationReportRequest(lrr); + Utils.printMessage(log, super.stack.getDictionary(), lrr.getMessage(), true); + this.sentLRR = true; + } + + /* (non-Javadoc) + * @see org.mobicents.diameter.stack.functional.slg.AbstractIDeferredClient#doLocationReportAnswerEvent( + * org.jdiameter.api.slg.ClientSLgSession, org.jdiameter.api.slg.events.LocationReportRequest, org.jdiameter.api.slg.events.LocationReportAnswer) + */ + + @Override + public void doLocationReportAnswerEvent(ClientSLgSession session, LocationReportRequest request, LocationReportAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + Utils.printMessage(log, super.stack.getDictionary(), answer.getMessage(), false); + + if (this.receivedLRA) { + fail("Received PLA more than once", null); + return; + } + this.receivedLRA = true; + } + + @Override + protected String getLCSNameString() { + String lcsNameString = "Restcomm Geolocation API"; + return lcsNameString; + } + + @Override + protected int getLCSFormatIndicator() { + /* + "0" = "LOGICAL_NAME" + "1" = "EMAIL_ADDRESS" + "2" = "MSISDN" + "3" = "URL" + "4" = "SIP_URL" + */ + int lcsFormatIndicator = 2; + return lcsFormatIndicator; + } + + @Override + protected String getUserName() { + // Information Element IMSI Mapped to AVP User-Name + String imsi = "748039876543210"; + return imsi; + } + + @Override + protected byte[] getMSISDN() { + String msisdnString = "59899077937"; + byte[] msisdn = msisdnString.getBytes(); + return msisdn; + } + + @Override + protected String getIMEI() { + String imei = "011714004661057"; + return imei; + } + + @Override + protected long getDeferredLocationType() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.36 + Bit Event Type Description + 0 UE-Available Any event in which the SGSN has established a contact with the UE. + 1 Entering-Into-Area An event where the UE enters a pre-defined geographical area. + 2 Leaving-From-Area An event where the UE leaves a pre-defined geographical area. + 3 Being-Inside-Area An event where the UE is currently within the pre-defined geographical area.For this event, + the value of Occurrence-Info AVP is always treated as set to “ONE_TIME_EVENT”. + 4 Periodic-LDR An event where a defined periodic timer expires in the UE and activates a location report or a location request. + */ + long deferredLocationType = 8; + return deferredLocationType; + } + + @Override + protected byte[] getLCSReferenceNumber() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.37 + The LCS-Reference-Number AVP is of type OctetString of length 1. It shall contain the reference number identifying the deferred location request. + */ + String lcsRefNumber = "4C4353353739"; + byte[] lcsRefNum = lcsRefNumber.getBytes(); + return lcsRefNum; + } + + @Override + protected java.net.InetAddress getGMLCAddress() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.7 + The GMLC-Address AVP is of type Address and shall contain the IPv4 or IPv6 address of H-GMLC or the V-GMLC associated with the serving node. + */ + try { + java.net.InetAddress gmlcAddress = java.net.InetAddress.getLocalHost(); + return gmlcAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected long getReportingAmount() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.46 + The Reporting-Amount AVP is of type Unsigned32 and it contains reporting frequency. Its minimum value shall be 1 and maximum value shall be 8639999. + */ + long reportingAmount = 8639910L; + return reportingAmount; + } + + @Override + protected long getReportingInterval() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.47 + The Interval-Time AVP is of type Unsigned32 and it contains reporting frequency. Its minimum value shall be 1 and maximum value shall be 8639999. + */ + long reportingInterval = 8639998L; + return reportingInterval; + } + + @Override + protected int getLocationEvent() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.20 + EMERGENCY_CALL_ORIGINATION (0) + EMERGENCY_CALL_RELEASE (1) + MO_LR (2) + EMERGENCY_CALL_HANDOVER (3) + DEFERRED_MT_LR_RESPONSE (4) + DEFERRED_MO_LR_TTTP_INITIATION (5) + DELAYED_LOCATION_REPORTING (6) + */ + int locationEvent = 4; + return locationEvent; + } + + @Override + protected byte[] getLocationEstimate() { + String locEstimate = "N43°38'19.39\" W116°14'28.86\""; + byte[] locationEstimate = locEstimate.getBytes(); + return locationEstimate; + } + + @Override + protected int getAccuracyFulfilmentIndicator() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.15 + REQUESTED_ACCURACY_FULFILLED (0) + REQUESTED_ACCURACY_NOT_FULFILLED (1) + */ + int accuracyFulfilmentIndicator = 0; + return accuracyFulfilmentIndicator; + } + + @Override + protected long getAgeOfLocationEstimate() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.19 + The Age-Of-Location-Estimate AVP is of type Unsigned32. + It indicates how long ago the location estimate was obtained in minutes, as indicated in 3GPP TS 29.002 [19]. + */ + long ageOfLocationEstimate = 374312L; + return ageOfLocationEstimate; + } + + @Override + protected byte[] getVelocityEstimate() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.17 + The Velocity-Estimate AVP is of type OctetString. + It is composed of 4 or more octets with an internal structure according to 3GPP TS 23.032 [3]. + */ + String vel = "210"; + byte[] velocityEstimate = vel.getBytes(); + return velocityEstimate; + } + + @Override + protected byte[] getEUTRANPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.18 + The EUTRAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "Positioning-Data" Information Element as defined in 3GPP TS 29.171 [7]. + */ + String eutran = "654E423435336C7465613233"; + byte[] eutranPositioningData = eutran.getBytes(); + return eutranPositioningData; + } + + @Override + protected byte[] getECGI() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.19 + The ECGI AVP is of type OctetString. It indicates the E-UTRAN Cell Global Identifier. + It is coded according to clause 8.21.5, in 3GPP TS 29.274 [8]. + */ + String eCgi = "654E4239343337"; + byte[] ecgi = eCgi.getBytes(); + return ecgi; + } + + @Override + protected byte[] getGERANPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.30 + The GERAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "Positioning Data" Information Element as defined in 3GPP TS 49.031 [20] + */ + String geran = "42545339343342534333"; + byte[] geranPositioningData = geran.getBytes(); + return geranPositioningData; + } + + @Override + protected byte[] getGERANGANSSPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.30 + The GERAN-GANSS-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "GANSS Positioning Data" Information Element as defined in 3GPP TS 49.031 [20] + */ + String geranGanss = "4254533733524E4331473433"; + byte[] geranGanssPositioningData = geranGanss.getBytes(); + return geranGanssPositioningData; + } + + @Override + protected byte[] getCellGlobalIdentity() { + String cgi = "9342784713907"; + byte[] CellGlobalIdentity = cgi.getBytes(); + return CellGlobalIdentity; + } + + @Override + protected byte[] getUTRANPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.33 + The UTRAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "positioningDataDiscriminator" and the "positioningDataSet" included in the + "positionData" Information Element as defined in 3GPP TS 25.413 [21]. + */ + String utran = "4E42393433524E4331"; + byte[] utranPositioningData = utran.getBytes(); + return utranPositioningData; + } + + @Override + protected byte[] getUTRANGANSSPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.33 + The UTRAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "positioningDataDiscriminator" and the "positioningDataSet" included in the + "positionData" Information Element as defined in 3GPP TS 25.413 [21]. + */ + String utranGanss = "4E42303331524E4335473433"; + byte[] utranGanssPositioningData = utranGanss.getBytes(); + return utranGanssPositioningData; + } + + @Override + protected byte[] getServiceAreaIdentity() { + /* + 3GPP TS 29.172 v13.0.0 -> 3GPP TS 29.272 + SAI shall contain the current service area of the target UE. The Service Area Identifier (SAI) is used to globally identify a service area. + This Information Element is applicable only when the UE is attached to UTRAN access and when the message is sent by the SGSN or combined MME/SGSN + */ + String sai = "service-area-umts-3"; + byte[] serviceAreaIdentity = sai.getBytes(); + return serviceAreaIdentity; + } + + @Override + protected long getLSCServiceTypeId() { + long lcsServiceTypeId = 234567012L; + return lcsServiceTypeId; + } + + @Override + protected int getPseudonymIndicator() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.21 + PSEUDONYM_NOT_REQUESTED (0) + PSEUDONYM_REQUESTED (1) + */ + int pseudonymIndicator = 0; + return pseudonymIndicator; + } + + @Override + protected int getLCSQoSClass() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.27 + ASSURED (0) + BEST EFFORT (1) + */ + int lcsQoSClass = 1; + return lcsQoSClass; + } + + @Override + protected byte[] getSGSNNumber() { + String sgsnNumString = "59899004501"; + byte[] sgsnNumber = sgsnNumString.getBytes(); + return sgsnNumber; + } + + @Override + protected String getSGSNName() { + String sgsnName = "SGSN01"; + return sgsnName; + } + + @Override + protected String getSGSNRealm() { + String sgsnRealm = "sgsn.restcomm.com"; + return sgsnRealm; + } + + @Override + protected String getMMEName() { + String mmeName = "MME710"; + return mmeName; + } + + @Override + protected String getMMERealm() { + String mmeRealm = "mme.restcomm.com"; + return mmeRealm; + } + + @Override + protected byte[] getMSCNumber() { + String mscNumString = "59899001207"; + byte[] mscNumber = mscNumString.getBytes(); + return mscNumber; + } + + @Override + protected String get3GPPAAAServerName() { + String tgppAAAServerName = "aaa.restcomm.com"; + return tgppAAAServerName; + } + + @Override + protected long getLCSCapabilitiesSets() { + long lcsCapabilitiesSets = 99900123L; + return lcsCapabilitiesSets; + } + + @Override + protected long getLRRFLags() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.35 + Bit Event Type Description + 0 Lgd/SLg-Indicator This bit, when set, indicates that the Location Report Request message is sent on the Lgd interface, + i.e. the source node is an SGSN (or a combined MME/SGSN to which the UE is attached via UTRAN or GERAN). + This bit, when cleared, indicates that the Location Report Request message is sent on the SLg interface, + i.e. the source node is an MME (or a combined MME/SGSN to which the UE is attached via E-UTRAN). + 1 MO-LR-ShortCircuit-Indicator This bit, when set, indicates that the MO-LR short circuit feature is used by the UE for + location estimate. This bit is applicable only when for deferred MT-LR procedure and + when the message is sent over Lgd interface. + 2 MO-LR-ShortCircuit-Requested This bit, when set, indicates that the UE is requesting to use MO-LR short circuit feature + for location estimate. + This bit is applicable only when periodic MO-LR TTTP procedure is initiated by the UE and when the + message is sent over Lgd interface. + */ + long lrrFlags = 1; + return lrrFlags; + } + + @Override + protected long getTerminationCause() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.55 + "Normal" 0 + "Error Undefined" 1 + "Internal Timeout" 2 + "Congestion" 3 + "MT_LR_Restart" 4 + "Privacy Violation" 5 + "Shape of Location Estimate Not Supported" 6 + "Subscriber Termination" 7 + "UE Termination" 8 + "Network Termination" 9 + */ + long terminationCause = 7; + return terminationCause; + } + + @Override + protected long getCellPortionId() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.58 + The Cell-Portion-ID AVP is of type Unsigned32. It indicates the current Cell Portion location of the target UE as provided by the E-SMLC. + It shall contain the value of the "Cell Portion ID" Information Element as defined in 3GPP TS 29.171 + */ + long cellPortionId = 349232432L; + return cellPortionId; + } + + @Override + protected byte[] get1xRTTRCID() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.59 + The 1xRTT-RCID AVP is of type OctetString. + It indicates the 1xRTT Reference Cell Id that consists of a Cell Identification Discriminator and a Cell Identification and shall be formatted + according to octets 3 through the end of the Cell Identifier element defined in subclause 4.2.17 in 3GPP2 A.S0014-D [22]. + The allowable cell discriminator values are "0000 0010", and "0000 0111". + */ + String oxrttrcid = "00000010"; + byte[] onexrttrcid = oxrttrcid.getBytes(); + return onexrttrcid; + } + + @Override + protected String getCivicAddress() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.61 + The Civic-Address AVP is of type UTF8String. + It contains the XML document carried in the "Civic Address" Information Element as defined in 3GPP TS 29.171. + */ + String civicAddress = "\n" + + " UK\n" + + " Devon\n" + + " Monkokehampton\n" + + " Deckport\n" + + " Cross\n" + + "\n" + + " 21451338\n" + + "\n" + + " "; // From IETF RFC 6848, Extended Civic Address Example + return civicAddress; + } + + @Override + protected long getBarometricPressure() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.62 + The Barometric-Pressure AVP is of type Unsigned32. + It contains the "Barometric Pressure" Information Element as defined in 3GPP TS 29.171. + */ + long barometricPressure = 101327L; + return barometricPressure; + } + + public boolean isReceivedLRA() { + return receivedLRA; + } + + public boolean isSentLRR() { + return sentLRR; + } + +} + diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ClientPLR.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ClientPLR.java new file mode 100644 index 000000000..bb7555594 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ClientPLR.java @@ -0,0 +1,516 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg.base; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.mobicents.diameter.stack.functional.Utils; +import org.mobicents.diameter.stack.functional.slg.AbstractImmediateClient; + +import static sun.jdbc.odbc.JdbcOdbcObject.hexStringToByteArray; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ClientPLR extends AbstractImmediateClient { + + protected boolean receivedPLA; + protected boolean sentPLR; + + public ClientPLR() { + } + + public void sendProvideLocationRequest() throws Exception { + ProvideLocationRequest plr = super.createPLR(super.clientSLgSession); + super.clientSLgSession.sendProvideLocationRequest(plr); + Utils.printMessage(log, super.stack.getDictionary(), plr.getMessage(), true); + this.sentPLR = true; + } + + /* (non-Javadoc) + * @see org.mobicents.diameter.stack.functional.slg.AbstractImmediateClient#doProvideLocationAnswerEvent( + * org.jdiameter.api.slg.ClientSLgSession, org.jdiameter.api.slg.events.ProvideLocationRequest, org.jdiameter.api.slg.events.ProvideLocationAnswer) + */ + @Override + public void doProvideLocationAnswerEvent(ClientSLgSession session, ProvideLocationRequest request, ProvideLocationAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + Utils.printMessage(log, super.stack.getDictionary(), answer.getMessage(), false); + + if (this.receivedPLA) { + fail("Received PLA more than once", null); + return; + } + this.receivedPLA = true; + } + + // PLR methods + + // { SLg-Location-Type } + protected int getSLgLocationType() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.2 + The SLg-Location-Type AVP is of type Enumerated. The following values are defined: + CURRENT_LOCATION (0) + CURRENT_OR_LAST_KNOWN_LOCATION (1) + INITIAL_LOCATION (2) + ACTIVATE_DEFERRED_LOCATION (3) + CANCEL_DEFERRED_LOCATION (4) + NOTIFICATION_VERIFICATION_ONLY (5) + */ + int slgLocationType = 0; + return slgLocationType; + } + + @Override + protected String getLCSNameString() { + String lcsNameString = "Restcomm Geolocation API"; + return lcsNameString; + } + + protected int getLCSFormatIndicator() { + /* + "0" = "LOGICAL_NAME" + "1" = "EMAIL_ADDRESS" + "2" = "MSISDN" + "3" = "URL" + "4" = "SIP_URL" + */ + int lcsFormatIndicator = 2; + return lcsFormatIndicator; + } + + @Override + protected String getUserName() { + // Information Element IMSI Mapped to AVP User-Name + String imsi = "748039876543210"; + return imsi; + } + + @Override + protected byte[] getMSISDN() { + String msisdnString = "59899077937"; + byte[] msisdn = msisdnString.getBytes(); + return msisdn; + } + + @Override + protected String getIMEI() { + String imei = "011714004661057"; + return imei; + } + + @Override + protected int getLCSClientType() { + /* + "0" = "EMERGENCY_SERVICES" + "1" = "VALUE_ADDED_SERVICES" + "2" = "PLMN_OPERATOR_SERVICES" + "3" = "LAWFUL_INTERCEPT_SERVICES" + */ + int lcsClientType = 1; + return lcsClientType; + } + + @Override + protected String getLCSRequestorIdString() { + String lcsRequestorIdString = "restcomm_geolocation_23"; + return lcsRequestorIdString; + } + + @Override + protected int getReqLCSFormatIndicator() { + /* + "0" = "LOGICAL_NAME" + "1" = "EMAIL_ADDRESS" + "2" = "MSISDN" + "3" = "URL" + "4" = "SIP_URL" + */ + int requestorLCSFormatIndicator = 3; + return requestorLCSFormatIndicator; + } + + @Override + protected long getLCSPriority() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.5 + The LCS-Priority AVP is of type Unsigned32. It indicates the priority of the location request. + The value 0 shall indicate the highest priority, and the value 1 shall indicate normal priority. + All other values shall be treated as 1 (normal priority). For details, refer to 3GPP TS 22.071. + */ + int lcsPriority = 1; + return lcsPriority; + } + + @Override + protected int getLCSQoSClass() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.27 + ASSURED (0) + BEST EFFORT (1) + */ + int lcsQoSClass = 1; + return lcsQoSClass; + } + + @Override + protected long getHorizontalAccuracy() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.7 + The Horizontal-Accuracy AVP is of type Unsigned32. Bits 6-0 corresponds to Uncertainty Code defined in 3GPP TS 23.032 [3]. + The horizontal location error should be less than the error indicated by the uncertainty code with 67% confidence. + Bits 7 to 31 shall be ignored + */ + long horizontalAccuracy = 120L; + return horizontalAccuracy; + } + + @Override + protected long getVerticalAccuracy() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.8 + The Vertical-Accuracy AVP is of type Unsigned32. Bits 6-0 corresponds to Uncertainty Code defined in 3GPP TS 23.032 [3]. + The Vertical location error should be less than the error indicated by the uncertainty code with 67% confidence. + Bits 7 to 31 shall be ignored + */ + long verticalAccuracy = 3237L; + return verticalAccuracy; + } + + @Override + protected int getVerticalRequested() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.9 + VERTICAL_COORDINATE_IS_NOT REQUESTED (0) + VERTICAL_COORDINATE_IS_REQUESTED (1) + */ + int verticalRequested = 0; + return verticalRequested; + } + + @Override + protected int getResponseTime() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.11 + LOW_DELAY (0) + DELAY_TOLERANT (1) + */ + int responseTime = 1; + return responseTime; + } + + @Override + protected int getVelocityRequested() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.10 + VELOCITY_IS_NOT_REQUESTED (0) + VELOCITY_IS_REQUESTED (1) + */ + int velocityRequested = 0; + return velocityRequested; + } + + @Override + protected long getSupportedGADShapes() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.12 + The Supported-GAD-Shapes AVP is of type Unsigned32 and it shall contain a bitmask. + A node shall mark in the BIT STRING all Shapes defined in 3GPP TS 23.032 [3] it supports. + Bits 6-0 in shall indicate the supported Shapes defined in 3GPP TS 23.032 [3]. Bits 7 to 31 shall be ignored. + ellipsoidPoint (0) + ellipsoidPointWithUncertaintyCircle (1) + ellipsoidPointWithUncertaintyEllipse (2) + polygon (3) + ellipsoidPointWithAltitude (4) + ellipsoidPointWithAltitudeAndUncertaintyElipsoid (5) + ellipsoidArc (6) + */ + long supportedGADShapes = 3L; + return supportedGADShapes; + } + + @Override + protected long getLSCServiceTypeId() { + long lcsServiceTypeId = 234L; + return lcsServiceTypeId; + } + + @Override + protected String getLCSCodeword() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.1 + The LCS-Codeword AVP is of type UTF8String. + It indicates the potential codeword string to send in a notification message to the UE + */ + String lcsCodeword = "rcgl49f9f$#ERSD"; + return lcsCodeword; + } + + @Override + protected String getServiceSelection() { + String apn = "restcomm.org"; + return apn; + } + + @Override + protected int getLCSPrivacyCheckSession() { + /* + 3GPP TS 291.172 v13.0.0 section 7.4.22 + LCS-Privacy-Check-Session ::= + { LCS-Privacy-Check } + 3GPP TS 29.172 v13.0.0 section 7.4.14 + ALLOWED_WITHOUT_NOTIFICATION (0) + ALLOWED_WITH_NOTIFICATION (1) + ALLOWED_IF_NO_RESPONSE (2) + RESTRICTED_IF_NO_RESPONSE (3) + NOT_ALLOWED (4) + */ + int lcsPrivacyCheckSession = 2; + return lcsPrivacyCheckSession; + } + + @Override + protected int getLCSPrivacyCheckNonSession() { + /* + 3GPP TS 291.172 v13.0.0 section 7.4.22 + LCS-Privacy-Check-Non-Session ::= + { LCS-Privacy-Check } + 3GPP TS 29.172 v13.0.0 section 7.4.14 + ALLOWED_WITHOUT_NOTIFICATION (0) + ALLOWED_WITH_NOTIFICATION (1) + ALLOWED_IF_NO_RESPONSE (2) + RESTRICTED_IF_NO_RESPONSE (3) + NOT_ALLOWED (4) + */ + int lcsPrivacyCheckNonSession = 4; + return lcsPrivacyCheckNonSession; + } + + @Override + protected long getDeferredLocationType() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.36 + Bit Event Type Description + 0 UE-Available Any event in which the SGSN has established a contact with the UE. + 1 Entering-Into-Area An event where the UE enters a pre-defined geographical area. + 2 Leaving-From-Area An event where the UE leaves a pre-defined geographical area. + 3 Being-Inside-Area An event where the UE is currently within the pre-defined geographical area.For this event, + the value of Occurrence-Info AVP is always treated as set to “ONE_TIME_EVENT”. + 4 Periodic-LDR An event where a defined periodic timer expires in the UE and activates a location report or a location request. + */ + long deferredLocationType = 8L; + return deferredLocationType; + } + + @Override + protected byte[] getLCSReferenceNumber() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.37 + The LCS-Reference-Number AVP is of type OctetString of length 1. It shall contain the reference number identifying the deferred location request. + */ + String lcsRefNumber = "4C4353353739"; + byte[] lcsRefNum = lcsRefNumber.getBytes(); + return lcsRefNum; + } + + @Override + protected int getOccurrenceInfo() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.43 + The Occurrence-Info AVP is of type Enumerated. The following values are defined: + ONE_TIME_EVENT (0) + MULTIPLE_TIME_EVENT (1) + */ + int occurrenceInfo = 1; + return occurrenceInfo; + } + + @Override + protected long getIntervalTime() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.44 + The Interval-Time AVP is of type Unsigned32 and it contains minimum time interval between area reports, in seconds. + */ + long intervalTime = 3600L; + return intervalTime; + } + + @Override + protected long getAreaType() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.41 + "Country Code" 0 + "PLMN ID" 1 + "Location Area ID" 2 + "Routing Area ID" 3 + "Cell Global ID" 4 + "UTRAN Cell ID" 5 + */ + long areaType = 3L; + return areaType; + } + + @Override + protected byte[] getAreaIdentification() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.42 + The Area-Identification AVP is of type OctetString and shall contain the identification of the area applicable + for the change of area event based deferred location reporting. Octets are coded as described in 3GPP TS 29.002 [24]. + */ + String areaId = "617265613531"; + byte[] areaIdentification = areaId.getBytes(); + return areaIdentification; + } + + @Override + protected java.net.InetAddress getGMLCAddress() { + + try { + java.net.InetAddress gmlcAddress = java.net.InetAddress.getLocalHost(); + return gmlcAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected long getPLRFLags() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.52 + Bit Event Type Description + 0 MO-LR-ShortCircuit-Indicator This bit, when set, indicates that the MO-LR short circuit feature is requested + for the periodic location.This bit is applicable only when the deferred MT-LR procedure is + initiated for a periodic location event and when the message is sent over Lgd interface. + 1 Optimized-LCS-Proc-Req This bit, when set, indicates that the GMLC is requesting the optimized LCS procedure + for the combined MME/SGSN. This bit is applicable only when the MT-LR procedure is + initiated by the GMLC. The GMLC shall set this bit only when the HSS indicates the combined MME/SGSN + node supporting the optimized LCS procedure. + 2 Delayed-Location-Reporting-Support-Indicator This bit, when set, indicates that the GMLC supports delayed location reporting for UEs transiently + not reachable (e.g. UEs in extended idle mode DRX or Power Saving Mode) as specified in subclauses + 9.1.6 and 9.1.15 of 3GPP TS 23.271 [2], i.e. that the GMLC supports receiving a + PROVIDE SUBSCRIBER LOCATION RESPONSE with the UE-Transiently-Not-Reachable-Indicator set in the + PLA-Flags IE; and receiving the location information in a subsequent SUBSCRIBER LOCATION REPORT + when the UE becomes reachable. + */ + long plrFlags = 4L; + return plrFlags; + } + + @Override + protected long getReportingAmount() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.46 + The Reporting-Amount AVP is of type Unsigned32 and it contains reporting frequency. Its minimum value shall be 1 and maximum value shall be 8639999. + */ + long reportingAmount = 8639910L; + return reportingAmount; + } + + @Override + protected long getReportingInterval() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.47 + The Interval-Time AVP is of type Unsigned32 and it contains reporting frequency. Its minimum value shall be 1 and maximum value shall be 8639999. + */ + long reportingInterval = 8639998L; + return reportingInterval; + } + + @Override + protected int getPrioritizedListIndicator() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.51 + The Prioritized-List-Indicator AVP is of type Enumerated and it indicates if the PLMN-ID-List is provided in prioritized order or not. + NOT_PRIORITIZED (0) + PRIORITIZED (1) + */ + int prioritizedListIndicator = 0; + return prioritizedListIndicator; + } + + @Override + protected byte[] getVisitedPLMNId() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.49 + The PLMN-ID-List AVP is of type Grouped. + AVP format: + PLMN-ID-List ::= + { Visited-PLMN-Id } + [ Periodic-Location-Support-Indicator ] + *[ AVP ] + If not included, the default value of Periodic-Location-Support-Indicator shall be considered as "NOT_SUPPORTED" (0). + */ + byte[] visitedPlmnIdList = hexStringToByteArray("473800"); + return visitedPlmnIdList; + } + + @Override + protected int getPeriodicLocationSupportIndicator() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.50 + The Periodic-Location-Support-Indicator AVP is of type Enumerated and it indicates if the given PLMN-ID (indicated by Visited-PLMN-Id) + supports periodic location or not. + NOT_SUPPORTED (0) + SUPPORTED (1) + */ + int periodicLocationSupportIndicator = 1; + return periodicLocationSupportIndicator; + } + + public boolean isReceivedPLA() { + return receivedPLA; + } + + public boolean isSentPLR() { + return sentPLR; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/SLgSessionBasicDefFlowTest.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/SLgSessionBasicDefFlowTest.java new file mode 100644 index 000000000..0c3f517f6 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/SLgSessionBasicDefFlowTest.java @@ -0,0 +1,225 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg.base; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.DisconnectCause; +import org.jdiameter.api.Mode; +import org.jdiameter.api.Peer; +import org.jdiameter.api.PeerState; +import org.jdiameter.api.PeerTable; +import org.jdiameter.api.Stack; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * + * @author Fernando Mendioroz + * @author Alexandre Mendonca + * @author Bartosz Baranowski + */ +@RunWith(Parameterized.class) +public class SLgSessionBasicDefFlowTest { + // TODO: add test on replicated nodes ? + private ClientLRR clientNode; + private ServerLRA serverNode1; + private URI clientConfigURI; + private URI serverNode1ConfigURI; + + /** + * @param clientConfigUrl + * // @param node1 + * // @param node2 + * @param serverNode1ConfigURL + */ + + public SLgSessionBasicDefFlowTest(String clientConfigUrl, String serverNode1ConfigURL) throws Exception { + super(); + this.clientConfigURI = new URI(clientConfigUrl); + this.serverNode1ConfigURI = new URI(serverNode1ConfigURL); + } + + @Before + public void setUp() throws Exception { + try { + this.clientNode = new ClientLRR(); + this.serverNode1 = new ServerLRA(); + + this.serverNode1.init(new FileInputStream(new File(this.serverNode1ConfigURI)), "SERVER1"); + this.serverNode1.start(); + + this.clientNode.init(new FileInputStream(new File(this.clientConfigURI)), "CLIENT"); + this.clientNode.start(Mode.ANY_PEER, 10, TimeUnit.SECONDS); + Stack stack = this.clientNode.getStack(); + List peers = stack.unwrap(PeerTable.class).getPeerTable(); + if (peers.size() == 1) { + // ok + } + else if (peers.size() > 1) { + // works better with replicated, since disconnected peers are also listed + boolean foundConnected = false; + for (Peer p : peers) { + if (p.getState(PeerState.class).equals(PeerState.OKAY)) { + if (foundConnected) { + throw new Exception("Wrong number of connected peers: " + peers); + } + foundConnected = true; + } + } + } + else { + throw new Exception("Wrong number of connected peers: " + peers); + } + } + catch (Throwable e) { + e.printStackTrace(); + } + } + + @After + public void tearDown() { + if (this.serverNode1 != null) { + try { + this.serverNode1.stop(DisconnectCause.REBOOTING); + } + catch (Exception e) { + + } + this.serverNode1 = null; + } + + if (this.clientNode != null) { + try { + this.clientNode.stop(DisconnectCause.REBOOTING); + } + catch (Exception e) { + + } + this.clientNode = null; + } + } + + @Test + public void testLocationReportBasicFlow() throws Exception { + try { + // pain of parameter tests :) ? + clientNode.sendLocationReportRequest(); + waitForMessage(); + + serverNode1.sendLocationReportAnswer(); + waitForMessage(); + } + catch (Exception e) { + e.printStackTrace(); + fail(e.toString()); + } + + if (!serverNode1.isReceivedLRR()) { + StringBuilder sb = new StringBuilder("Did not receive LRR! "); + sb.append("Server ER:\n").append(serverNode1.createErrorReport(this.serverNode1.getErrors())); + + fail(sb.toString()); + } + if (!clientNode.isReceivedLRA()) { + StringBuilder sb = new StringBuilder("Did not receive LRA! "); + sb.append("Client ER:\n").append(clientNode.createErrorReport(this.clientNode.getErrors())); + + fail(sb.toString()); + } + + if (!clientNode.isPassed()) { + StringBuilder sb = new StringBuilder(); + sb.append("Client ER:\n").append(clientNode.createErrorReport(this.clientNode.getErrors())); + + fail(sb.toString()); + } + + if (!serverNode1.isPassed()) { + StringBuilder sb = new StringBuilder(); + sb.append("Server ER:\n").append(serverNode1.createErrorReport(this.serverNode1.getErrors())); + + fail(sb.toString()); + } + } + + @Parameters + public static Collection data() { + + String client = "configurations/functional-slg/config-client.xml"; + String server1 = "configurations/functional-slg/config-server-node1.xml"; + + //String replicatedClient = "configurations/functional-slh/replicated-config-client.xml"; + //String replicatedServer1 = "configurations/functional-slh/replicated-config-server-node1.xml"; + + Class t = SLgSessionBasicDefFlowTest.class; + client = t.getClassLoader().getResource(client).toString(); + server1 = t.getClassLoader().getResource(server1).toString(); + //replicatedClient = t.getClassLoader().getResource(replicatedClient).toString(); + //replicatedServer1 = t.getClassLoader().getResource(replicatedServer1).toString(); + + return Arrays.asList(new Object[][] { { client, server1 }/*, { replicatedClient, replicatedServer1 } */}); + } + + private void waitForMessage() { + try { + Thread.sleep(2000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/SLgSessionBasicImmFlowTest.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/SLgSessionBasicImmFlowTest.java new file mode 100644 index 000000000..dac67ed15 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/SLgSessionBasicImmFlowTest.java @@ -0,0 +1,225 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg.base; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.DisconnectCause; +import org.jdiameter.api.Mode; +import org.jdiameter.api.Peer; +import org.jdiameter.api.PeerState; +import org.jdiameter.api.PeerTable; +import org.jdiameter.api.Stack; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * + * @author Fernando Mendioroz + * @author Alexandre Mendonca + * @author Bartosz Baranowski + */ +@RunWith(Parameterized.class) +public class SLgSessionBasicImmFlowTest { + // TODO: add test on replicated nodes ? + private ClientPLR clientNode; + private ServerPLA serverNode1; + private URI clientConfigURI; + private URI serverNode1ConfigURI; + + /** + * @param clientConfigUrl + * @param serverNode1ConfigURL + * // @param node2 + * // @param serverCount + */ + public SLgSessionBasicImmFlowTest(String clientConfigUrl, String serverNode1ConfigURL) throws Exception { + super(); + this.clientConfigURI = new URI(clientConfigUrl); + this.serverNode1ConfigURI = new URI(serverNode1ConfigURL); + } + + @Before + public void setUp() throws Exception { + try { + this.clientNode = new ClientPLR(); + this.serverNode1 = new ServerPLA(); + + this.serverNode1.init(new FileInputStream(new File(this.serverNode1ConfigURI)), "SERVER1"); + this.serverNode1.start(); + + this.clientNode.init(new FileInputStream(new File(this.clientConfigURI)), "CLIENT"); + this.clientNode.start(Mode.ANY_PEER, 10, TimeUnit.SECONDS); + Stack stack = this.clientNode.getStack(); + List peers = stack.unwrap(PeerTable.class).getPeerTable(); + if (peers.size() == 1) { + // ok + } + else if (peers.size() > 1) { + // works better with replicated, since disconnected peers are also listed + boolean foundConnected = false; + for (Peer p : peers) { + if (p.getState(PeerState.class).equals(PeerState.OKAY)) { + if (foundConnected) { + throw new Exception("Wrong number of connected peers: " + peers); + } + foundConnected = true; + } + } + } + else { + throw new Exception("Wrong number of connected peers: " + peers); + } + } + catch (Throwable e) { + e.printStackTrace(); + } + } + + @After + public void tearDown() { + if (this.serverNode1 != null) { + try { + this.serverNode1.stop(DisconnectCause.REBOOTING); + } + catch (Exception e) { + + } + this.serverNode1 = null; + } + + if (this.clientNode != null) { + try { + this.clientNode.stop(DisconnectCause.REBOOTING); + } + catch (Exception e) { + + } + this.clientNode = null; + } + } + + @Test + public void testProvideLocationRequestBasicFlow() throws Exception { + try { + // pain of parameter tests :) ? + clientNode.sendProvideLocationRequest(); + waitForMessage(); + + serverNode1.sendProvideLocationAnswer(); + waitForMessage(); + + } + catch (Exception e) { + e.printStackTrace(); + fail(e.toString()); + } + + if (!serverNode1.isReceivedPLR()) { + StringBuilder sb = new StringBuilder("Did not receive PLR! "); + sb.append("Server ER:\n").append(serverNode1.createErrorReport(this.serverNode1.getErrors())); + + fail(sb.toString()); + } + if (!clientNode.isReceivedPLA()) { + StringBuilder sb = new StringBuilder("Did not receive PLA! "); + sb.append("Client ER:\n").append(clientNode.createErrorReport(this.clientNode.getErrors())); + + fail(sb.toString()); + } + + if (!clientNode.isPassed()) { + StringBuilder sb = new StringBuilder(); + sb.append("Client ER:\n").append(clientNode.createErrorReport(this.clientNode.getErrors())); + + fail(sb.toString()); + } + + if (!serverNode1.isPassed()) { + StringBuilder sb = new StringBuilder(); + sb.append("Server ER:\n").append(serverNode1.createErrorReport(this.serverNode1.getErrors())); + + fail(sb.toString()); + } + } + + @Parameters + public static Collection data() { + + String client = "configurations/functional-slg/config-client.xml"; + String server1 = "configurations/functional-slg/config-server-node1.xml"; + + //String replicatedClient = "configurations/functional-slh/replicated-config-client.xml"; + //String replicatedServer1 = "configurations/functional-slh/replicated-config-server-node1.xml"; + + Class t = SLgSessionBasicImmFlowTest.class; + client = t.getClassLoader().getResource(client).toString(); + server1 = t.getClassLoader().getResource(server1).toString(); + //replicatedClient = t.getClassLoader().getResource(replicatedClient).toString(); + //replicatedServer1 = t.getClassLoader().getResource(replicatedServer1).toString(); + + return Arrays.asList(new Object[][] { { client, server1 }/*, { replicatedClient, replicatedServer1 } */}); + } + + private void waitForMessage() { + try { + Thread.sleep(2000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ServerLRA.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ServerLRA.java new file mode 100644 index 000000000..c0b5ddbd4 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ServerLRA.java @@ -0,0 +1,227 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg.base; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.LocationReportAnswer; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.mobicents.diameter.stack.functional.Utils; +import org.mobicents.diameter.stack.functional.slg.AbstractDeferredServer; + +import static sun.jdbc.odbc.JdbcOdbcObject.hexStringToByteArray; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ServerLRA extends AbstractDeferredServer { + + protected boolean receivedLRR; + protected boolean sentLRA; + protected boolean receivedPLR; + + protected LocationReportRequest locationReportRequest; + protected ProvideLocationRequest provideLocationRequest; + + public void sendLocationReportAnswer() throws Exception { + if (!receivedLRR || locationReportRequest == null) { + fail("Did not receive LRR or answer already sent.", null); + throw new Exception("Did not receive LRR or answer already sent. Request: " + this.locationReportRequest); + } + + LocationReportAnswer lra = super.createLRA(locationReportRequest, 2001); + + super.serverSLgSession.sendLocationReportAnswer(lra); + + this.sentLRA = true; + locationReportRequest = null; + Utils.printMessage(log, super.stack.getDictionary(), lra.getMessage(), true); + } + + /* (non-Javadoc) + * @see org.mobicents.diameter.stack.functional.TBase#processRequest(org.jdiameter.api.Request) + */ + @Override + public Answer processRequest(Request request) { + int code = request.getCommandCode(); + if (code != LocationReportRequest.code) { + fail("Received Request with code not used by SLg!. Code[" + request.getCommandCode() + "]", null); + return null; + } + if (super.serverSLgSession != null) { + // do fail? + fail("Received Request in base listener, not in app specific!" + code, null); + } else { + try { + + super.serverSLgSession = this.sessionFactory.getNewAppSession(request.getSessionId(), getApplicationId(), ServerSLgSession.class, (Object) null); + ((NetworkReqListener) this.serverSLgSession).processRequest(request); + + } catch (Exception e) { + e.printStackTrace(); + fail(null, e); + } + } + return null; + } + + @Override + public void doLocationReportRequestEvent(ServerSLgSession session, LocationReportRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + if (this.receivedLRR) { + fail("Received LRR more than once", null); + return; + } + this.receivedLRR = true; + this.locationReportRequest = request; + } + + @Override + public void doProvideLocationRequestEvent(ServerSLgSession session, ProvideLocationRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + if (this.receivedPLR) { + fail("Received PLR more than once", null); + return; + } + this.receivedPLR = true; + this.provideLocationRequest = request; + } + + @Override + protected java.net.InetAddress getGMLCAddress() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.7 + The GMLC-Address AVP is of type Address and shall contain the IPv4 or IPv6 address of H-GMLC or the V-GMLC associated with the serving node. + */ + try { + java.net.InetAddress gmlcAddress = java.net.InetAddress.getLocalHost(); + return gmlcAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected long getLRAFLags() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.56 + Bit Event Type Description + 0 MO-LR-ShortCircuit-Indicator This bit, when set, indicates that the MO-LR short circuit feature is used for obtaining location estimate. + This bit is applicable only when the message is sent over Lgd interface. + */ + long lraFlags = 0; + return lraFlags; + } + + @Override + protected int getPrioritizedListIndicator() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.51 + The Prioritized-List-Indicator AVP is of type Enumerated and it indicates if the PLMN-ID-List is provided in prioritized order or not. + NOT_PRIORITIZED (0) + PRIORITIZED (1) + */ + int prioritizedListIndicator = 0; + return prioritizedListIndicator; + } + + @Override + protected byte[] getVisitedPLMNId() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.49 + The PLMN-ID-List AVP is of type Grouped. + AVP format: + PLMN-ID-List ::= + { Visited-PLMN-Id } + [ Periodic-Location-Support-Indicator ] + *[ AVP ] + If not included, the default value of Periodic-Location-Support-Indicator shall be considered as "NOT_SUPPORTED" (0). + */ + byte[] visitedPlmnIdList = hexStringToByteArray("471800"); + return visitedPlmnIdList; + } + + @Override + protected int getPeriodicLocationSupportIndicator() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.50 + The Periodic-Location-Support-Indicator AVP is of type Enumerated and it indicates if the given PLMN-ID (indicated by Visited-PLMN-Id) + supports periodic location or not. + NOT_SUPPORTED (0) + SUPPORTED (1) + */ + int periodicLocationSupportIndicator = 1; + return periodicLocationSupportIndicator; + } + + @Override + protected byte[] getLCSReferenceNumber() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.37 + The LCS-Reference-Number AVP is of type OctetString of length 1. It shall contain the reference number identifying the deferred location request. + */ + String lcsRefNumber = "4C4353353739"; + byte[] lcsRefNum = lcsRefNumber.getBytes(); + return lcsRefNum; + } + + public boolean isReceivedLRR() { + return receivedLRR; + } + + public boolean isSentLRA() { + return sentLRA; + } + +} + diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ServerPLA.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ServerPLA.java new file mode 100644 index 000000000..b82de66b1 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slg/base/ServerPLA.java @@ -0,0 +1,408 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slg.base; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.slg.ServerSLgSession; +import org.jdiameter.api.slg.events.LocationReportRequest; +import org.jdiameter.api.slg.events.ProvideLocationRequest; +import org.jdiameter.api.slg.events.ProvideLocationAnswer; +import org.mobicents.diameter.stack.functional.Utils; +import org.mobicents.diameter.stack.functional.slg.AbstractImmediateServer; + +/** + * + * @author Fernando Mendioroz + * + */ +public class ServerPLA extends AbstractImmediateServer { + + protected boolean receivedPLR; + protected boolean sentPLA; + protected boolean receivedLRR; + + protected ProvideLocationRequest provideLocationRequest; + protected LocationReportRequest locationReportRequest; + + public void sendProvideLocationAnswer() throws Exception { + if (!receivedPLR || provideLocationRequest == null) { + fail("Did not receive PLR or answer already sent.", null); + throw new Exception("Did not receive PLR or answer already sent. Request: " + this.provideLocationRequest); + } + + ProvideLocationAnswer pla = super.createPLA(provideLocationRequest, 2001); + + super.serverSLgSession.sendProvideLocationAnswer(pla); + + this.sentPLA = true; + provideLocationRequest = null; + Utils.printMessage(log, super.stack.getDictionary(), pla.getMessage(), true); + } + + + /* (non-Javadoc) + * @see org.mobicents.diameter.stack.functional.TBase#processRequest(org.jdiameter.api.Request) + */ + @Override + public Answer processRequest(Request request) { + int code = request.getCommandCode(); + if (code != ProvideLocationRequest.code) { + fail("Received Request with code not used by SLg!. Code[" + request.getCommandCode() + "]", null); + return null; + } + if (super.serverSLgSession != null) { + // do fail? + fail("Received Request in base listener, not in app specific!" + code, null); + } else { + try { + + super.serverSLgSession = this.sessionFactory.getNewAppSession(request.getSessionId(), getApplicationId(), ServerSLgSession.class, (Object) null); + ((NetworkReqListener) this.serverSLgSession).processRequest(request); + + } catch (Exception e) { + e.printStackTrace(); + fail(null, e); + } + } + return null; + } + + @Override + public void doProvideLocationRequestEvent(ServerSLgSession session, ProvideLocationRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + if (this.receivedPLR) { + fail("Received PLR more than once", null); + return; + } + this.receivedPLR = true; + this.provideLocationRequest = request; + } + + @Override + public void doLocationReportRequestEvent(ServerSLgSession session, LocationReportRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + if (this.receivedLRR) { + fail("Received LRR more than once", null); + return; + } + this.receivedLRR = true; + this.locationReportRequest = request; + } + + @Override + protected byte[] getLocationEstimate() { + String locEstimate = "S35°38'15.37\" WE109°45'21.77\""; + byte[] locationEstimate = locEstimate.getBytes(); + return locationEstimate; + } + + @Override + protected int getAccuracyFulfilmentIndicator() { +/* + 3GPP TS 29.172 v13.0.0 section 7.4.15 + REQUESTED_ACCURACY_FULFILLED (0) + REQUESTED_ACCURACY_NOT_FULFILLED (1) +*/ + int accuracyFulfilmentIndicator = 0; + return accuracyFulfilmentIndicator; + } + + @Override + protected long getAgeOfLocationEstimate() { +/* + 3GPP TS 29.172 v13.0.0 section 7.4.19 + The Age-Of-Location-Estimate AVP is of type Unsigned32. + It indicates how long ago the location estimate was obtained in minutes, as indicated in 3GPP TS 29.002 [19]. +*/ + long ageOfLocationEstimate = 37L; + return ageOfLocationEstimate; + } + + @Override + protected byte[] getVelocityEstimate() { +/* + 3GPP TS 29.172 v13.0.0 section 7.4.17 + The Velocity-Estimate AVP is of type OctetString. + It is composed of 4 or more octets with an internal structure according to 3GPP TS 23.032 [3]. +*/ + String vel = "210"; + byte[] velocityEstimate = vel.getBytes(); + return velocityEstimate; + } + + @Override + protected byte[] getEUTRANPositioningData() { +/* + 3GPP TS 29.172 v13.0.0 section 7.4.18 + The EUTRAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "Positioning-Data" Information Element as defined in 3GPP TS 29.171 [7]. +*/ + String eutran = "654E423435336C7465613233"; + byte[] eutranPositioningData = eutran.getBytes(); + return eutranPositioningData; + } + + @Override + protected byte[] getECGI() { +/* + 3GPP TS 29.172 v13.0.0 section 7.4.19 + The ECGI AVP is of type OctetString. It indicates the E-UTRAN Cell Global Identifier. + It is coded according to clause 8.21.5, in 3GPP TS 29.274 [8]. +*/ + String eCgi = "654E4239343337"; + byte[] ecgi = eCgi.getBytes(); + return ecgi; + } + + @Override + protected byte[] getGERANPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.30 + The GERAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "Positioning Data" Information Element as defined in 3GPP TS 49.031 [20] + */ + String geran = "42545339343342534333"; + byte[] geranPositioningData = geran.getBytes(); + return geranPositioningData; + } + + @Override + protected byte[] getGERANGANSSPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.30 + The GERAN-GANSS-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "GANSS Positioning Data" Information Element as defined in 3GPP TS 49.031 [20] + */ + String geranGanss = "4254533733524E4331473433"; + byte[] geranGanssPositioningData = geranGanss.getBytes(); + return geranGanssPositioningData; + } + + @Override + protected byte[] getCellGlobalIdentity() { + String cgi = "A342784713907"; + byte[] CellGlobalIdentity = cgi.getBytes(); + return CellGlobalIdentity; + } + + @Override + protected byte[] getUTRANPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.33 + The UTRAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "positioningDataDiscriminator" and the "positioningDataSet" included in the + "positionData" Information Element as defined in 3GPP TS 25.413 [21]. + */ + String utran = "4E42393433524E4331"; + byte[] utranPositioningData = utran.getBytes(); + return utranPositioningData; + } + + @Override + protected byte[] getUTRANGANSSPositioningData() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.33 + The UTRAN-Positioning-Data AVP is of type OctetString. + It shall contain the encoded content of the "positioningDataDiscriminator" and the "positioningDataSet" included in the + "positionData" Information Element as defined in 3GPP TS 25.413 [21]. + */ + String utranGanss = "4E42303331524E4335473433"; + byte[] utranGanssPositioningData = utranGanss.getBytes(); + return utranGanssPositioningData; + } + + @Override + protected byte[] getServiceAreaIdentity() { + /* + 3GPP TS 29.172 v13.0.0 -> 3GPP TS 29.272 + SAI shall contain the current service area of the target UE. The Service Area Identifier (SAI) is used to globally identify a service area. + This Information Element is applicable only when the UE is attached to UTRAN access and when the message is sent by the SGSN or combined MME/SGSN + */ + String sai = "736572766963652D617265612D756D74732D33"; + byte[] serviceAreaIdentity = sai.getBytes(); + return serviceAreaIdentity; + } + + @Override + protected byte[] getSGSNNumber() { + String sgsnNumString = "59899004501"; + byte[] sgsnNumber = sgsnNumString.getBytes(); + return sgsnNumber; + } + + @Override + protected String getSGSNName() { + String sgsnName = "SGSN01"; + return sgsnName; + } + + @Override + protected String getSGSNRealm() { + String sgsnRealm = "sgsn.restcomm.com"; + return sgsnRealm; + } + + @Override + protected String getMMEName() { + String mmeName = "MME710"; + return mmeName; + } + + @Override + protected String getMMERealm() { + String mmeRealm = "mme.restcomm.com"; + return mmeRealm; + } + + @Override + protected byte[] getMSCNumber() { + String mscNumString = "59899001207"; + byte[] mscNumber = mscNumString.getBytes(); + return mscNumber; + } + + @Override + protected String get3GPPAAAServerName() { + String tgppAAAServerName = "aaa.restcomm.com"; + return tgppAAAServerName; + } + + @Override + protected long getLCSCapabilitiesSets() { + long lcsCapabilitiesSets = 99900123L; + return lcsCapabilitiesSets; + } + + @Override + protected java.net.InetAddress getGMLCAddress() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.7 + The GMLC-Address AVP is of type Address and shall contain the IPv4 or IPv6 address of H-GMLC or the V-GMLC associated with the serving node. + */ + try { + java.net.InetAddress gmlcAddress = java.net.InetAddress.getLocalHost(); + return gmlcAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected long getPLAFLags() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.53 + Bit Event Type Description + 0 Deferred-MT-LR-Response-Indicator This bit, when set, indicates that the message is sent in response to the deferred-MT location request. + This bit is applicable only when the message is sent over Lgd interface. + 1 MO-LR-ShortCircuit-Indicator This bit, when set, indicates that the MO-LR short circuit feature is accepted by the UE, + for periodic location reporting. This bit is applicable only when the message is sent over Lgd interface. + 2 Optimized-LCS-Proc-Performed This bit, when set, indicates that the combined MME/SGSN has performed the optimized LCS procedure + to retrieve the location of the target UE. This bit is applicable only when the message is sent for + the MT-LR procedure. + 3 UE-Transiently-Not-Reachable-Indicator This bit, when set, indicates that the UE is transiently not reachable due to power saving + (e.g. UE is in extended idle mode DRX or in Power Saving Mode), and that the location information + will be returned in a subsequent Subscriber Location Report when the UE becomes reachable. + */ + long plaFlags = 8L; + return plaFlags; + } + + @Override + protected long getCellPortionId() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.58 + The Cell-Portion-ID AVP is of type Unsigned32. It indicates the current Cell Portion location of the target UE as provided by the E-SMLC. + It shall contain the value of the "Cell Portion ID" Information Element as defined in 3GPP TS 29.171 + */ + long cellPortionId = 34923L; + return cellPortionId; + } + + @Override + protected String getCivicAddress() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.61 + The Civic-Address AVP is of type UTF8String. + It contains the XML document carried in the "Civic Address" Information Element as defined in 3GPP TS 29.171. + */ + String civicAddress = "\n" + + " US\n" + + " CA\n" + + " Sacramento\n" + + " Colorado\n" + + " 223\n" + + " Boulevard\n" + + " A\n" + + " "; // From IETF RFC 6848, XML Example with Street Type Prefix and House Number Prefix + return civicAddress; + } + + @Override + protected long getBarometricPressure() { + /* + 3GPP TS 29.172 v13.0.0 section 7.4.62 + The Barometric-Pressure AVP is of type Unsigned32. + It contains the "Barometric Pressure" Information Element as defined in 3GPP TS 29.171. + */ + long barometricPressure = 101327L; + return barometricPressure; + } + + public boolean isReceivedPLR() { + return receivedPLR; + } + + public boolean isSentPLA() { + return sentPLA; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/AbstractClient.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/AbstractClient.java new file mode 100644 index 000000000..6711b1597 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/AbstractClient.java @@ -0,0 +1,213 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slh; + +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpSet; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.Mode; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ClientSLhSessionListener; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.slh.LCSRoutingInfoRequestImpl; +import org.jdiameter.common.impl.app.slh.SLhSessionFactoryImpl; +import org.mobicents.diameter.stack.functional.TBase; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class AbstractClient extends TBase implements ClientSLhSessionListener { + + // NOTE: implementing NetworkReqListener since its required for stack to + // know we support it... ech. + + protected ClientSLhSession clientSLhSession; + + public void init(InputStream configStream, String clientID) throws Exception { + try { + super.init(configStream, clientID, ApplicationId.createByAuthAppId(10415, 16777291)); + SLhSessionFactoryImpl slhSessionFactory = new SLhSessionFactoryImpl(this.sessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLhSession.class, slhSessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLhSession.class, slhSessionFactory); + + slhSessionFactory.setClientSessionListener(this); + + this.clientSLhSession = ((ISessionFactory) this.sessionFactory).getNewAppSession(this.sessionFactory.getSessionId("xx-SLh-TESTxx"), getApplicationId(), + ClientSLhSession.class, null); + } + finally { + try { + configStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // ----------- delegate methods so + + public void start() throws IllegalDiameterStateException, InternalException { + stack.start(); + } + + public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { + stack.start(mode, timeOut, timeUnit); + } + + public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { + stack.stop(timeOut, timeUnit, disconnectCause); + } + + public void stop(int disconnectCause) { + stack.stop(disconnectCause); + } + + // ------- def methods, to fail :) + + public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"Other\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doLCSRoutingInfoAnswerEvent(ClientSLhSession session, LCSRoutingInfoRequest request, LCSRoutingInfoAnswer answer) throws InternalException, + IllegalDiameterStateException, RouteException, OverloadException { + fail("Received \"RIA\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + // ----------- conf + + public String getSessionId() { + return this.clientSLhSession.getSessionId(); + } + + public ClientSLhSession getSession() { + return this.clientSLhSession; + } + + protected abstract String getUserName(); + protected abstract byte[] getMSISDN(); + protected abstract byte[] getGMLCNumber(); + + // ----------- 3GPP TS 29.173 reference + + protected LCSRoutingInfoRequest createRIR(ClientSLhSession slhSession) throws Exception { + /* + < LCS-Routing-Info-Request> ::= < Diameter Header: 8388622, REQ, PXY, 16777291 > + + < Session-Id > + [ Vendor-Specific-Application-Id ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + [ Destination-Host ] + { Destination-Realm } + [ User-Name ] + [ MSISDN ] + [ GMLC-Number ] + *[ Supported-Features ] + *[ Proxy-Info ] + *[ Route-Record ] + *[ AVP ] + + */ + // Create LCSRoutingInfoRequest + LCSRoutingInfoRequest rir = new LCSRoutingInfoRequestImpl(slhSession.getSessions().get(0).createRequest(LCSRoutingInfoRequest.code, getApplicationId(), + getServerRealmName())); + // < LCS-Routing-Info-Request> ::= < Diameter Header: 8388622, REQ, PXY, 16777291 > + + AvpSet reqSet = rir.getMessage().getAvps(); + + if (reqSet.getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { + AvpSet vendorSpecificApplicationId = reqSet.addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, 0, false, false); + // 1* [ Vendor-Id ] + vendorSpecificApplicationId.addAvp(Avp.VENDOR_ID, getApplicationId().getVendorId(), true); + // 0*1{ Auth-Application-Id } + vendorSpecificApplicationId.addAvp(Avp.AUTH_APPLICATION_ID, getApplicationId().getAuthAppId(), true); + } + + // { Auth-Session-State } + if (reqSet.getAvp(Avp.AUTH_SESSION_STATE) == null) { + reqSet.addAvp(Avp.AUTH_SESSION_STATE, 1); + } + + // { Origin-Host } + reqSet.removeAvp(Avp.ORIGIN_HOST); + reqSet.addAvp(Avp.ORIGIN_HOST, getClientURI(), true); + + // [ User-Name ] + String userName = getUserName(); + if (userName != null) { + reqSet.addAvp(Avp.USER_NAME, userName, 10415, true, false, false); + } + + // [ MSISDN ] + byte[] msisdn = getMSISDN(); + if (msisdn != null){ + reqSet.addAvp(Avp.MSISDN, msisdn, 10415, true, false); + } + + // [ GMLC-Number ] + byte[] gmlcNumber = getGMLCNumber(); + if (gmlcNumber != null){ + reqSet.addAvp(Avp.GMLC_NUMBER, gmlcNumber, 10415, false, false); + } + + return rir; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/AbstractServer.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/AbstractServer.java new file mode 100644 index 000000000..52c716bba --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/AbstractServer.java @@ -0,0 +1,356 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slh; + +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.ApplicationId; +import org.jdiameter.api.Avp; +import org.jdiameter.api.AvpSet; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.Mode; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.app.AppAnswerEvent; +import org.jdiameter.api.app.AppRequestEvent; +import org.jdiameter.api.app.AppSession; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.api.slh.ServerSLhSessionListener; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.jdiameter.client.api.ISessionFactory; +import org.jdiameter.common.impl.app.slh.LCSRoutingInfoAnswerImpl; +import org.jdiameter.common.impl.app.slh.SLhSessionFactoryImpl; +import org.mobicents.diameter.stack.functional.TBase; + +/** + * + * @author Fernando Mendioroz + * + */ +public abstract class AbstractServer extends TBase implements ServerSLhSessionListener { + + // NOTE: implementing NetworkReqListener since its required for stack to + // know we support it... ech. + + protected ServerSLhSession serverSLhSession; + + public void init(InputStream configStream, String clientID) throws Exception { + try { + super.init(configStream, clientID, ApplicationId.createByAuthAppId(10415, 16777291)); + SLhSessionFactoryImpl slhSessionFactory = new SLhSessionFactoryImpl(this.sessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLhSession.class, slhSessionFactory); + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLhSession.class, slhSessionFactory); + slhSessionFactory.setServerSessionListener(this); + } + finally { + try { + configStream.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + } + + // ----------- delegate methods so + + public void start() throws IllegalDiameterStateException, InternalException { + stack.start(); + } + + public void start(Mode mode, long timeOut, TimeUnit timeUnit) throws IllegalDiameterStateException, InternalException { + stack.start(mode, timeOut, timeUnit); + } + + public void stop(long timeOut, TimeUnit timeUnit, int disconnectCause) throws IllegalDiameterStateException, InternalException { + stack.stop(timeOut, timeUnit, disconnectCause); + } + + public void stop(int disconnectCause) { + stack.stop(disconnectCause); + } + + public void doOtherEvent(AppSession session, AppRequestEvent request, AppAnswerEvent answer) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"Other\" event, request[" + request + "], answer[" + answer + "], on session[" + session + "]", null); + } + + public void doLCSRoutingInfoRequestEvent(ServerSLhSession session, LCSRoutingInfoRequest request) throws InternalException, IllegalDiameterStateException, + RouteException, OverloadException { + fail("Received \"RIR\" event, request[" + request + "], on session[" + session + "]", null); + } + + // -------- conf + + public String getSessionId() { + return this.serverSLhSession.getSessionId(); + } + + public void fetchSession(String sessionId) throws InternalException { + this.serverSLhSession = stack.getSession(sessionId, ServerSLhSession.class); + } + + public ServerSLhSession getSession() { + return this.serverSLhSession; + } + + protected abstract String getUserName(); + protected abstract byte[] getMSISDN(); + protected abstract byte[] getLMSI(); + protected abstract byte[] getSGSNNumber(); + protected abstract String getSGSNName(); + protected abstract String getSGSNRealm(); + protected abstract String getMMEName(); + protected abstract String getMMERealm(); + protected abstract byte[] getMSCNumber(); + protected abstract String get3GPPAAAServerName(); + protected abstract long getLCSCapabilitiesSets(); + protected abstract java.net.InetAddress getGMLCAddress(); + protected abstract byte[] getAdditionalSGSNNumber(); + protected abstract String getAdditionalSGSNName(); + protected abstract String getAdditionalSGSNRealm(); + protected abstract String getAdditionalMMEName(); + protected abstract String getAdditionalMMERealm(); + protected abstract byte[] getAdditionalMSCNumber(); + protected abstract String getAdditional3GPPAAAServerName(); + protected abstract long getAdditionalLCSCapabilitiesSets(); + protected abstract java.net.InetAddress getAdditionalGMLCAddress(); + protected abstract java.net.InetAddress getPPRAddress(); + protected abstract long getRIAFLags(); + + // ----------- 3GPP TS 29.173 reference + + public LCSRoutingInfoAnswer createRIA(LCSRoutingInfoRequest rir, long resultCode) throws Exception { + +/* + < LCS-Routing-Info-Answer> ::= < Diameter Header: 8388622, PXY, 16777291 > + + < Session-Id > + [ Vendor-Specific-Application-Id ] + [ Result-Code ] + [ Experimental-Result ] + { Auth-Session-State } + { Origin-Host } + { Origin-Realm } + *[ Supported-Features ] + [ User-Name ] + [ MSISDN ] + [ LMSI ] + [ Serving-Node ] + *[ Additional-Serving-Node ] + [ GMLC-Address ] + [ PPR-Address ] + [ RIA-Flags ] + *[ AVP ] + *[ Failed-AVP ] + *[ Proxy-Info ] + *[ Route-Record ] + + */ + LCSRoutingInfoAnswer ria = new LCSRoutingInfoAnswerImpl((Request) rir.getMessage(), resultCode); + + AvpSet reqSet = rir.getMessage().getAvps(); + AvpSet set = ria.getMessage().getAvps(); + set.removeAvp(Avp.DESTINATION_HOST); + set.removeAvp(Avp.DESTINATION_REALM); + set.addAvp(reqSet.getAvp(Avp.AUTH_APPLICATION_ID)); + + // { Vendor-Specific-Application-Id } + if (set.getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) { + AvpSet vendorSpecificApplicationId = set.addGroupedAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, 0, false, false); + // 1* [ Vendor-Id ] + vendorSpecificApplicationId.addAvp(Avp.VENDOR_ID, getApplicationId().getVendorId(), true); + // 0*1{ Auth-Application-Id } + vendorSpecificApplicationId.addAvp(Avp.AUTH_APPLICATION_ID, getApplicationId().getAuthAppId(), true); + } + // [ Result-Code ] + // [ Experimental-Result ] + // { Auth-Session-State } + if (set.getAvp(Avp.AUTH_SESSION_STATE) == null) { + set.addAvp(Avp.AUTH_SESSION_STATE, 1); + } + + // [ User-Name ] + String userName = getUserName(); + if (userName != null) { + set.addAvp(Avp.USER_NAME, userName, 10415, true, false, false); + } + + // [ MSISDN ] + byte[] msisdn = getMSISDN(); + if (msisdn != null){ + set.addAvp(Avp.MSISDN, msisdn, 10415, true, false); + } + + // [ LMSI ] + byte[] lmsi = getLMSI(); + if (lmsi != null){ + set.addAvp(Avp.LMSI, lmsi, 10415, true, false); + } + +/* + Serving-Node ::= + [ SGSN-Number ] + [ SGSN-Name ] + [ SGSN-Realm ] + [ MME-Name ] + [ MME-Realm ] + [ MSC-Number ] + [ 3GPP-AAA-Server-Name ] + [ LCS-Capabilities-Sets ] + [ GMLC-Address ] + *[AVP] + +*/ + AvpSet servingNode = set.addGroupedAvp(Avp.SERVING_NODE, 10415, true, false); + byte[] sgsnNumber = getSGSNNumber(); + String sgsnName= getSGSNName(); + String sgsnRealm = getSGSNRealm(); + String mmeName = getMMEName(); + String mmeRealm = getMMERealm(); + byte[] mscNumber = getMSCNumber(); + String tgppAAAServerName= get3GPPAAAServerName(); + long lcsCapabilitiesSet = getLCSCapabilitiesSets(); + java.net.InetAddress gmlcAddress = getGMLCAddress(); + + if (sgsnNumber != null){ + servingNode.addAvp(Avp.SGSN_NUMBER, sgsnNumber, 10415, false, false); + } + if (sgsnName != null){ + servingNode.addAvp(Avp.SGSN_NAME, sgsnName, 10415, false, false, false); + } + if (sgsnRealm != null){ + servingNode.addAvp(Avp.SGSN_REALM, sgsnRealm, 10415, false, false, false); + } + if (mmeName != null){ + servingNode.addAvp(Avp.MME_NAME, mmeName, 10415, false, false, false); + } + if (mmeRealm != null){ + servingNode.addAvp(Avp.MME_REALM, mmeRealm, 10415, false, false, false); + } + if (mscNumber != null){ + servingNode.addAvp(Avp.MSC_NUMBER, mscNumber, 10415, false, false); + } + if (tgppAAAServerName != null){ + servingNode.addAvp(Avp.TGPP_AAA_SERVER_NAME, tgppAAAServerName, 10415, false, false, false); + } + if (lcsCapabilitiesSet != -1){ + servingNode.addAvp(Avp.LCS_CAPABILITIES_SETS, lcsCapabilitiesSet, 10415, false, false, true); + } + if (gmlcAddress != null){ + servingNode.addAvp(Avp.GMLC_ADDRESS, gmlcAddress, 10415, false, false); + } + +/* + Additional-Serving-Node ::= + [ SGSN-Number ] + [ MME-Name ] + [ SGSN-Name ] + [ SGSN-Realm ] + [ MME-Realm ] + [ MSC-Number ] + [ 3GPP-AAA-Server-Name ] + [ LCS-Capabilities-Sets ] + [ GMLC-Address ] + *[AVP] +*/ + AvpSet additionalServingNode = set.addGroupedAvp(Avp.ADDITIONAL_SERVING_NODE, 10415, true, false); + byte[] additionalSGSNNumber = getAdditionalSGSNNumber(); + String additionalSGSNName = getAdditionalSGSNName(); + String additionalSGSNRealm = getAdditionalSGSNRealm(); + String additionalMMEName = getAdditionalMMEName(); + String additionalMMERealm = getAdditionalMMERealm(); + byte[] additionalMSCNumber = getAdditionalMSCNumber(); + String additional3GPPAAAServerName = getAdditional3GPPAAAServerName(); + long additionalLCSCapabilitiesSets = getAdditionalLCSCapabilitiesSets(); + java.net.InetAddress additionalGMLCAddress = getAdditionalGMLCAddress(); + + if (additionalSGSNNumber != null){ + additionalServingNode.addAvp(Avp.SGSN_NUMBER, additionalSGSNNumber, 10415, false, false); + } + if (additionalSGSNName != null){ + additionalServingNode.addAvp(Avp.SGSN_NAME, additionalSGSNName, 10415, false, false, false); + } + if (additionalSGSNRealm != null){ + additionalServingNode.addAvp(Avp.SGSN_REALM, additionalSGSNRealm, 10415, false, false, false); + } + if (additionalMMEName != null){ + additionalServingNode.addAvp(Avp.MME_NAME, additionalMMEName, 10415, false, false, false); + } + if (additionalMMERealm != null){ + additionalServingNode.addAvp(Avp.MME_REALM, additionalMMERealm, 10415, false, false, false); + } + if (additionalMSCNumber != null){ + additionalServingNode.addAvp(Avp.MSC_NUMBER, additionalMSCNumber, 10415, false, false); + } + if (additional3GPPAAAServerName != null){ + additionalServingNode.addAvp(Avp.TGPP_AAA_SERVER_NAME, additional3GPPAAAServerName, 10415, false, false, false); + } + if (additionalLCSCapabilitiesSets != -1){ + additionalServingNode.addAvp(Avp.LCS_CAPABILITIES_SETS, additionalLCSCapabilitiesSets, 10415, false, false, true); + } + if (additionalGMLCAddress != null){ + additionalServingNode.addAvp(Avp.GMLC_ADDRESS, additionalGMLCAddress, 10415, false, false); + } + + // [ PPR-Address ] + java.net.InetAddress pprAddress = getPPRAddress(); + if (pprAddress != null){ + set.addAvp(Avp.PPR_ADDRESS, pprAddress, 10415, true, false); + } + + //[ RIA-Flags ] + long riafLags = getRIAFLags(); + if (riafLags != -1){ + set.addAvp(Avp.RIA_FLAGS, riafLags, 10415, true, false, true); + } + + return ria; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/Client.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/Client.java new file mode 100644 index 000000000..27518fa4d --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/Client.java @@ -0,0 +1,120 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slh.base; + +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.mobicents.diameter.stack.functional.Utils; +import org.mobicents.diameter.stack.functional.slh.AbstractClient; + +/** + * + * @author Fernando Mendioroz + * + */ +public class Client extends AbstractClient { + + protected boolean receivedRIA; + protected boolean sentRIR; + + public Client() { + } + + public void sendLCSRoutingInfoRequest() throws Exception { + LCSRoutingInfoRequest rir = super.createRIR(super.clientSLhSession); + super.clientSLhSession.sendLCSRoutingInfoRequest(rir); + Utils.printMessage(log, super.stack.getDictionary(), rir.getMessage(), true); + this.sentRIR = true; + } + + /* (non-Javadoc) + * @see org.mobicents.diameter.stack.functional.slh.AbstractImmediateClient#doLCSRoutingInfoAnswerEvent( + * org.jdiameter.api.slh.ClientSLhSession, org.jdiameter.api.slh.events.LCSRoutingInfoRequest, org.jdiameter.api.slh.events.LCSRoutingInfoAnswer) + */ + @Override + public void doLCSRoutingInfoAnswerEvent(ClientSLhSession session, LCSRoutingInfoRequest request, LCSRoutingInfoAnswer answer) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + Utils.printMessage(log, super.stack.getDictionary(), answer.getMessage(), false); + + if (this.receivedRIA) { + fail("Received RIA more than once", null); + return; + } + this.receivedRIA = true; + } + + @Override + protected String getUserName() { + // Information Element IMSI Mapped to AVP User-Name + String imsi = "748039876543210"; + return imsi; + } + + @Override + protected byte[] getMSISDN() { + String msisdnString = "59899077937"; + byte[] msisdn = msisdnString.getBytes(); + return msisdn; + } + + @Override + protected byte[] getGMLCNumber() { + String gmlcNumberString = "759834279"; + byte[] gmlcNumber = gmlcNumberString.getBytes(); + return gmlcNumber; + } + + public boolean isReceivedRIA() { + return receivedRIA; + } + + public boolean isSentRIR() { + return sentRIR; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/SLhSessionBasicFlowTest.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/SLhSessionBasicFlowTest.java new file mode 100644 index 000000000..5aeee79dd --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/SLhSessionBasicFlowTest.java @@ -0,0 +1,223 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slh.base; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.jdiameter.api.DisconnectCause; +import org.jdiameter.api.Mode; +import org.jdiameter.api.Peer; +import org.jdiameter.api.PeerState; +import org.jdiameter.api.PeerTable; +import org.jdiameter.api.Stack; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +/** + * @author Fernando Mendioroz + * @author Alexandre Mendonca + * @author Bartosz Baranowski + */ +@RunWith(Parameterized.class) +public class SLhSessionBasicFlowTest { + // TODO: add test on replicated nodes ? + private Client clientNode; + private Server serverNode1; + private URI clientConfigURI; + private URI serverNode1ConfigURI; + + /** + * @param clientConfigUrl + * @param serverNode1ConfigURL + * // @param node2 + * // @param serverCount + */ + public SLhSessionBasicFlowTest(String clientConfigUrl, String serverNode1ConfigURL) throws Exception { + super(); + this.clientConfigURI = new URI(clientConfigUrl); + this.serverNode1ConfigURI = new URI(serverNode1ConfigURL); + } + + @Before + public void setUp() throws Exception { + try { + this.clientNode = new Client(); + this.serverNode1 = new Server(); + + this.serverNode1.init(new FileInputStream(new File(this.serverNode1ConfigURI)), "SERVER1"); + this.serverNode1.start(); + + this.clientNode.init(new FileInputStream(new File(this.clientConfigURI)), "CLIENT"); + this.clientNode.start(Mode.ANY_PEER, 10, TimeUnit.SECONDS); + Stack stack = this.clientNode.getStack(); + List peers = stack.unwrap(PeerTable.class).getPeerTable(); + if (peers.size() == 1) { + // ok + } + else if (peers.size() > 1) { + // works better with replicated, since disconnected peers are also listed + boolean foundConnected = false; + for (Peer p : peers) { + if (p.getState(PeerState.class).equals(PeerState.OKAY)) { + if (foundConnected) { + throw new Exception("Wrong number of connected peers: " + peers); + } + foundConnected = true; + } + } + } + else { + throw new Exception("Wrong number of connected peers: " + peers); + } + } + catch (Throwable e) { + e.printStackTrace(); + } + } + + @After + public void tearDown() { + if (this.serverNode1 != null) { + try { + this.serverNode1.stop(DisconnectCause.REBOOTING); + } + catch (Exception e) { + + } + this.serverNode1 = null; + } + + if (this.clientNode != null) { + try { + this.clientNode.stop(DisconnectCause.REBOOTING); + } + catch (Exception e) { + + } + this.clientNode = null; + } + } + + @Test + public void testLCSRoutingInfo() throws Exception { + try { + // pain of parameter tests :) ? + clientNode.sendLCSRoutingInfoRequest(); + waitForMessage(); + + serverNode1.sendLCSRoutingInfoAnswer(); + waitForMessage(); + } + catch (Exception e) { + e.printStackTrace(); + fail(e.toString()); + } + + if (!serverNode1.isReceivedRIR()) { + StringBuilder sb = new StringBuilder("Did not receive RIR! "); + sb.append("Server ER:\n").append(serverNode1.createErrorReport(this.serverNode1.getErrors())); + + fail(sb.toString()); + } + if (!clientNode.isReceivedRIA()) { + StringBuilder sb = new StringBuilder("Did not receive RIA! "); + sb.append("Client ER:\n").append(clientNode.createErrorReport(this.clientNode.getErrors())); + + fail(sb.toString()); + } + + if (!clientNode.isPassed()) { + StringBuilder sb = new StringBuilder(); + sb.append("Client ER:\n").append(clientNode.createErrorReport(this.clientNode.getErrors())); + + fail(sb.toString()); + } + + if (!serverNode1.isPassed()) { + StringBuilder sb = new StringBuilder(); + sb.append("Server ER:\n").append(serverNode1.createErrorReport(this.serverNode1.getErrors())); + + fail(sb.toString()); + } + } + + @Parameters + public static Collection data() { + + String client = "configurations/functional-slh/config-client.xml"; + String server1 = "configurations/functional-slh/config-server-node1.xml"; + + //String replicatedClient = "configurations/functional-slh/replicated-config-client.xml"; + //String replicatedServer1 = "configurations/functional-slh/replicated-config-server-node1.xml"; + + Class t = SLhSessionBasicFlowTest.class; + client = t.getClassLoader().getResource(client).toString(); + server1 = t.getClassLoader().getResource(server1).toString(); + //replicatedClient = t.getClassLoader().getResource(replicatedClient).toString(); + //replicatedServer1 = t.getClassLoader().getResource(replicatedServer1).toString(); + + return Arrays.asList(new Object[][] { { client, server1 }/*, { replicatedClient, replicatedServer1 } */}); + } + + private void waitForMessage() { + try { + Thread.sleep(2000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/Server.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/Server.java new file mode 100644 index 000000000..a44436942 --- /dev/null +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/functional/slh/base/Server.java @@ -0,0 +1,318 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2016, 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 + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * JBoss, Home of Professional Open Source + * Copyright 2007-2011, Red Hat, 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.mobicents.diameter.stack.functional.slh.base; + +import org.jdiameter.api.Answer; +import org.jdiameter.api.IllegalDiameterStateException; +import org.jdiameter.api.InternalException; +import org.jdiameter.api.NetworkReqListener; +import org.jdiameter.api.OverloadException; +import org.jdiameter.api.Request; +import org.jdiameter.api.RouteException; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.api.slh.events.LCSRoutingInfoRequest; +import org.jdiameter.api.slh.events.LCSRoutingInfoAnswer; +import org.mobicents.diameter.stack.functional.Utils; +import org.mobicents.diameter.stack.functional.slh.AbstractServer; + +import java.net.UnknownHostException; + +/** + * + * @author Fernando Mendioroz + * + */ +public class Server extends AbstractServer { + + protected boolean receivedRIR; + protected boolean sentRIA; + + protected LCSRoutingInfoRequest request; + + public void sendLCSRoutingInfoAnswer() throws Exception { + if (!receivedRIR || request == null) { + fail("Did not receive RIR or answer already sent.", null); + throw new Exception("Did not receive RIR or answer already sent. Request: " + this.request); + } + + LCSRoutingInfoAnswer ria = super.createRIA(request, 2001); + + super.serverSLhSession.sendLCSRoutingInfoAnswer(ria); + + this.sentRIA = true; + request = null; + Utils.printMessage(log, super.stack.getDictionary(), ria.getMessage(), true); + } + + /* (non-Javadoc) + * @see org.mobicents.diameter.stack.functional.TBase#processRequest(org.jdiameter.api.Request) + */ + @Override + public Answer processRequest(Request request) { + int code = request.getCommandCode(); + if (code != LCSRoutingInfoRequest.code) { + fail("Received Request with code not used by SLh!. Code[" + request.getCommandCode() + "]", null); + return null; + } + if (super.serverSLhSession != null) { + // do fail? + fail("Received Request in base listener, not in app specific!" + code, null); + } else { + try { + + super.serverSLhSession = this.sessionFactory.getNewAppSession(request.getSessionId(), getApplicationId(), ServerSLhSession.class, (Object) null); + ((NetworkReqListener) this.serverSLhSession).processRequest(request); + + } catch (Exception e) { + e.printStackTrace(); + fail(null, e); + } + } + return null; + } + @Override + public void doLCSRoutingInfoRequestEvent(ServerSLhSession session, LCSRoutingInfoRequest request) + throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { + if (this.receivedRIR) { + fail("Received RIR more than once", null); + return; + } + this.receivedRIR = true; + this.request = request; + } + + @Override + protected String getUserName() { + // Information Element IMSI Mapped to AVP User-Name + String imsi = "748039876543210"; + return imsi; + } + + @Override + protected byte[] getMSISDN() { + String msisdnString = "59899077937"; + byte[] msisdn = msisdnString.getBytes(); + return msisdn; + } + + @Override + protected byte[] getLMSI() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.2 + The LMSI AVP is of type OctetString and it shall contain the Local Mobile Station Identity (LMSI) allocated by the VLR, as defined in 3GPP TS 23.003 + */ + String lmsiString = "748031234567890"; + byte[] lmsi = lmsiString.getBytes(); + return lmsi; + } + + @Override + protected byte[] getSGSNNumber() { + String sgsnNumString = "59899004501"; + byte[] sgsnNumber = sgsnNumString.getBytes(); + return sgsnNumber; + } + + @Override + protected String getSGSNName() { + String sgsnName = "SGSN01"; + return sgsnName; + } + + @Override + protected String getSGSNRealm() { + String sgsnRealm = "sgsn.restcomm.com"; + return sgsnRealm; + } + + @Override + protected String getMMEName() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.4 + TThe MME-Name AVP is of type DiameterIdentity and it shall contain the Diameter identity of the serving MME. + */ + String mmeName = "MME710"; + return mmeName; + } + + @Override + protected String getMMERealm() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.12 + The MME-Realm AVP is of type DiameterIdentity and it shall contain the Diameter Realm Identity of the serving MME. + */ + String mmeRealm = "mme.restcomm.com"; + return mmeRealm; + } + + @Override + protected byte[] getMSCNumber() { + String mscNumString = "59899001207"; + byte[] mscNumber = mscNumString.getBytes(); + return mscNumber; + } + + @Override + protected String get3GPPAAAServerName() { + String tgppAAAServerName = "aaa.restcomm.com"; + return tgppAAAServerName; + } + + @Override + protected long getLCSCapabilitiesSets() { + long lcsCapabilitiesSets = 99900123L; + return lcsCapabilitiesSets; + } + + @Override + protected byte[] getAdditionalSGSNNumber() { + String sgsnNumString = "59899004502"; + byte[] sgsnNumber = sgsnNumString.getBytes(); + return sgsnNumber; + } + + @Override + protected String getAdditionalSGSNName() { + String sgsnName = "SGSN02"; + return sgsnName; + } + + @Override + protected String getAdditionalSGSNRealm() { + String sgsnRealm = "sgsn2.restcomm.com"; + return sgsnRealm; + } + + @Override + protected String getAdditionalMMEName() { + String mmeName = "MME712"; + return mmeName; + } + + @Override + protected String getAdditionalMMERealm() { + String mmeRealm = "mme2.restcomm.com"; + return mmeRealm; + } + + @Override + protected byte[] getAdditionalMSCNumber() { + String mscNumString = "59899001210"; + byte[] mscNumber = mscNumString.getBytes(); + return mscNumber; + } + + @Override + protected String getAdditional3GPPAAAServerName() { + String tgppAAAServerName = "aaa2.restcomm.com"; + return tgppAAAServerName; + } + + @Override + protected long getAdditionalLCSCapabilitiesSets() { + long lcsCapabilitiesSets = 88800123L; + return lcsCapabilitiesSets; + } + + @Override + protected java.net.InetAddress getAdditionalGMLCAddress() { + try { + java.net.InetAddress gmlcAddress = java.net.InetAddress.getLocalHost(); + return gmlcAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected java.net.InetAddress getGMLCAddress() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.7 + The GMLC-Address AVP is of type Address and shall contain the IPv4 or IPv6 address of H-GMLC or the V-GMLC associated with the serving node. + */ + try { + java.net.InetAddress gmlcAddress = java.net.InetAddress.getLocalHost(); + return gmlcAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected java.net.InetAddress getPPRAddress() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.9 + The PPR-Address AVP is of type Address and contains the IPv4 or IPv6 address of the Privacy Profile Register for the targeted user + */ + try { + java.net.InetAddress pprAddress = java.net.InetAddress.getLocalHost(); + return pprAddress; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected long getRIAFLags() { + /* + 3GPP TS 29.173 v13.0.0 section 6.4.15 + Bit Event Type Description + 0 Combined-MME/SGSN-Supporting-Optimized-LCS-Proc This bit, when set, indicates that the UE is served by the MME and the SGSN parts of the same + combined MME/SGSN and this combined MME/SGSN supports the optimized LCS procedure. + */ + long riaFlags = 1L; + return riaFlags; + } + + public boolean isReceivedRIR() { + return receivedRIR; + } + + public boolean isSentRIA() { + return sentRIA; + } + +} \ No newline at end of file diff --git a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/sessions/SessionsWithAppIdTest.java b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/sessions/SessionsWithAppIdTest.java index 815e5ba80..f3ab36d22 100644 --- a/testsuite/tests/src/test/java/org/mobicents/diameter/stack/sessions/SessionsWithAppIdTest.java +++ b/testsuite/tests/src/test/java/org/mobicents/diameter/stack/sessions/SessionsWithAppIdTest.java @@ -49,6 +49,10 @@ import org.jdiameter.api.s13.ServerS13Session; import org.jdiameter.api.sh.ClientShSession; import org.jdiameter.api.sh.ServerShSession; +import org.jdiameter.api.slh.ClientSLhSession; +import org.jdiameter.api.slh.ServerSLhSession; +import org.jdiameter.api.slg.ClientSLgSession; +import org.jdiameter.api.slg.ServerSLgSession; import org.jdiameter.client.api.ISessionFactory; import org.jdiameter.common.api.app.IAppSessionFactory; import org.jdiameter.common.api.app.acc.ClientAccSessionState; @@ -75,6 +79,8 @@ import org.jdiameter.common.impl.app.ro.RoSessionFactoryImpl; import org.jdiameter.common.impl.app.s13.S13SessionFactoryImpl; import org.jdiameter.common.impl.app.sh.ShSessionFactoryImpl; +import org.jdiameter.common.impl.app.slh.SLhSessionFactoryImpl; +import org.jdiameter.common.impl.app.slg.SLgSessionFactoryImpl; import org.jdiameter.server.impl.StackImpl; import org.junit.Assert; import org.junit.Test; @@ -102,6 +108,8 @@ public class SessionsWithAppIdTest { private static final ApplicationId GQ_APPID = ApplicationId.createByAuthAppId(10415, 16777222); private static final ApplicationId GX_APPID = ApplicationId.createByAuthAppId(10415, 16777224); private static final ApplicationId S13_APPID = ApplicationId.createByAuthAppId(10415, 16777252); + private static final ApplicationId SLh_APPID = ApplicationId.createByAuthAppId(10415, 16777291); + private static final ApplicationId SLg_APPID = ApplicationId.createByAuthAppId(10415, 16777255); static { @@ -426,4 +434,40 @@ public void testS13ServerSessionStartsIdleState() throws Exception { Assert.assertEquals(state.IDLE, state); } + @Test + public void testSLhClientSessionHasAppId() throws Exception { + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLhSession.class, new SLhSessionFactoryImpl(sessionFactory)); + ClientSLhSession session = sessionFactory.getNewAppSession("accesspoint7.acme.com;1876543210;" + lowSessionId++, SLh_APPID, ClientSLhSession.class); + + ApplicationId sessionAppId = session.getSessionAppId(); + Assert.assertEquals("Session Application-Id should be the same as indicated.", SLh_APPID, sessionAppId); + } + + @Test + public void testSLhServerSessionHasAppId() throws Exception { + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLhSession.class, new SLhSessionFactoryImpl(sessionFactory)); + ServerSLhSession session = sessionFactory.getNewAppSession("accesspoint7.acme.com;1876543210;" + lowSessionId++, SLh_APPID, ServerSLhSession.class); + + ApplicationId sessionAppId = session.getSessionAppId(); + Assert.assertEquals("Session Application-Id should be the same as indicated.", SLh_APPID, sessionAppId); + } + + @Test + public void testSLgClientSessionHasAppId() throws Exception { + ((ISessionFactory) sessionFactory).registerAppFacory(ClientSLgSession.class, new SLgSessionFactoryImpl(sessionFactory)); + ClientSLgSession session = sessionFactory.getNewAppSession("accesspoint7.acme.com;1876543210;" + lowSessionId++, SLg_APPID, ClientSLgSession.class); + + ApplicationId sessionAppId = session.getSessionAppId(); + Assert.assertEquals("Session Application-Id should be the same as indicated.", SLg_APPID, sessionAppId); + } + + @Test + public void testSLgServerSessionHasAppId() throws Exception { + ((ISessionFactory) sessionFactory).registerAppFacory(ServerSLgSession.class, new SLgSessionFactoryImpl(sessionFactory)); + ServerSLgSession session = sessionFactory.getNewAppSession("accesspoint7.acme.com;1876543210;" + lowSessionId++, SLg_APPID, ServerSLgSession.class); + + ApplicationId sessionAppId = session.getSessionAppId(); + Assert.assertEquals("Session Application-Id should be the same as indicated.", SLg_APPID, sessionAppId); + } + } diff --git a/testsuite/tests/src/test/resources/configurations/functional-slg/config-client.xml b/testsuite/tests/src/test/resources/configurations/functional-slg/config-client.xml new file mode 100644 index 000000000..d663da1c0 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slg/config-client.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slg/config-server-node1.xml b/testsuite/tests/src/test/resources/configurations/functional-slg/config-server-node1.xml new file mode 100644 index 000000000..a5b65bbf0 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slg/config-server-node1.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slg/config-server-node2.xml b/testsuite/tests/src/test/resources/configurations/functional-slg/config-server-node2.xml new file mode 100644 index 000000000..61aebd8d6 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slg/config-server-node2.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-client.xml b/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-client.xml new file mode 100644 index 000000000..d87e0ae2c --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-client.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-server-node1.xml b/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-server-node1.xml new file mode 100644 index 000000000..ece62abc3 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-server-node1.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-server-node2.xml b/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-server-node2.xml new file mode 100644 index 000000000..9da5cd39b --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slg/replicated-config-server-node2.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slh/config-client.xml b/testsuite/tests/src/test/resources/configurations/functional-slh/config-client.xml new file mode 100644 index 000000000..cd09ef13b --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slh/config-client.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slh/config-server-node1.xml b/testsuite/tests/src/test/resources/configurations/functional-slh/config-server-node1.xml new file mode 100644 index 000000000..2dcf09d7a --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slh/config-server-node1.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slh/config-server-node2.xml b/testsuite/tests/src/test/resources/configurations/functional-slh/config-server-node2.xml new file mode 100644 index 000000000..c36746f75 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slh/config-server-node2.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-client.xml b/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-client.xml new file mode 100644 index 000000000..f3c4987a5 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-client.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-server-node1.xml b/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-server-node1.xml new file mode 100644 index 000000000..522ae1a9d --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-server-node1.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-server-node2.xml b/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-server-node2.xml new file mode 100644 index 000000000..f8db942e5 --- /dev/null +++ b/testsuite/tests/src/test/resources/configurations/functional-slh/replicated-config-server-node2.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/tests/src/test/resources/dictionary.xml b/testsuite/tests/src/test/resources/dictionary.xml index 6f7c02bc2..a63b6aaee 100644 --- a/testsuite/tests/src/test/resources/dictionary.xml +++ b/testsuite/tests/src/test/resources/dictionary.xml @@ -7867,4 +7867,637 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file