/** * */ package org.mobicents.tests.diameter.base.acr; import static org.jdiameter.common.api.app.acc.ServerAccSessionState.IDLE; import java.io.InputStream; import org.apache.log4j.Level; import org.jdiameter.api.Answer; import org.jdiameter.api.ApplicationId; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.AvpSet; import org.jdiameter.api.IllegalDiameterStateException; import org.jdiameter.api.InternalException; import org.jdiameter.api.Message; import org.jdiameter.api.Network; import org.jdiameter.api.OverloadException; import org.jdiameter.api.Request; import org.jdiameter.api.RouteException; import org.jdiameter.api.acc.ServerAccSession; import org.jdiameter.api.acc.ServerAccSessionListener; import org.jdiameter.api.acc.events.AccountRequest; 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.client.api.ISessionFactory; import org.jdiameter.common.impl.app.acc.AccSessionFactoryImpl; import org.jdiameter.common.impl.app.acc.AccountAnswerImpl; import org.jdiameter.server.impl.app.acc.ServerAccSessionImpl; import org.mobicents.tests.diameter.AbstractStackRunner; /** * @author baranowb * */ public class ACR extends AbstractStackRunner implements ServerAccSessionListener { private ApplicationId acrAppId = ApplicationId.createByAccAppId(193, 19302); private AccSessionFactoryImpl accSessionFactory; public ACR() { super(); // TODO Auto-generated constructor stub } @Override public void configure(InputStream f) throws Exception { // TODO Auto-generated method stub super.configure(f); // we must add ourselves Network network = stack.unwrap(Network.class); network.addNetworkReqListener(this, acrAppId); accSessionFactory = new AccSessionFactoryImpl(super.factory); accSessionFactory.setServerSessionListener(this); ((ISessionFactory) super.factory).registerAppFacory(ServerAccSession.class, accSessionFactory); } public Answer processRequest(Request request) { // here we should get ACR, and respond with ACA if (request.getCommandCode() != 271) { if (super.log.isEnabledFor(Level.ERROR)) { super.log.error("Received non ACR message, discarding."); dumpMessage(request, false); } return null; } ApplicationId appId = request.getApplicationIdAvps().isEmpty() ? null : request.getApplicationIdAvps().iterator().next(); try { // msg is processed as part of creation in this case. ServerAccSession session = ((ISessionFactory) stack.getSessionFactory()).getNewAppSession(request.getSessionId(), appId, ServerAccSession.class, request); session.addStateChangeNotification(new LocalStateChangeListener(session)); ((ServerAccSessionImpl) session).processRequest(request); } catch (InternalException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalDiameterStateException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public void receivedSuccessMessage(Request arg0, Answer arg1) { // we should not do that if (super.log.isEnabledFor(Level.ERROR)) { super.log.error("Received answer"); dumpMessage(arg1, false); } } public void timeoutExpired(Request arg0) { if (super.log.isInfoEnabled()) { super.log.info("Timeout expired"); dumpMessage(arg0, true); } } // ACR listener methods. public void doAccRequestEvent(ServerAccSession session, AccountRequest arg1) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // this is called when app session is created. Message answer = super.createAnswer((Request) arg1.getMessage(), 2001, arg1.getMessage().getApplicationIdAvps().iterator().next()); AvpSet set = answer.getAvps(); // { Accounting-Record-Type } try { set.addAvp(480, arg1.getAccountingRecordType()); } catch (AvpDataException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // { Accounting-Record-Number } try { set.addAvp(485, arg1.getAccountingRecordNumber(), true); } catch (AvpDataException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // hack. for Seagull to work..... try { AvpSet vendorSpecificApplicationId = set.getAvp(260).getGrouped(); // zero auth app id. vendorSpecificApplicationId.addAvp(258, 0L, true); } catch (AvpDataException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if (log.isInfoEnabled()) { log.info("Received Request: " + ((Request) arg1.getMessage()).getCommandCode() + "\nE2E:" + ((Request) arg1.getMessage()).getEndToEndIdentifier() + "\nHBH:" + ((Request) arg1.getMessage()).getHopByHopIdentifier() + "\nAppID:" + ((Request) arg1.getMessage()).getApplicationId()); log.info("Request AVPS: \n"); try { printAvps(((Request) arg1.getMessage()).getAvps()); } catch (AvpDataException e) { // TODO Auto-generated catch block e.printStackTrace(); } log.info("Created answer: " + answer.getCommandCode() + "\nE2E:" + answer.getEndToEndIdentifier() + "\nHBH:" + answer.getHopByHopIdentifier() + "\nAppID:" + answer.getApplicationId()); log.info("Answer AVPS: \n"); try { printAvps(answer.getAvps()); } catch (AvpDataException e) { // TODO Auto-generated catch block e.printStackTrace(); } } AccountAnswerImpl ans = new AccountAnswerImpl((Answer) answer); session.sendAccountAnswer(ans); } public void doOtherEvent(AppSession arg0, AppRequestEvent arg1, AppAnswerEvent arg2) throws InternalException, IllegalDiameterStateException, RouteException, OverloadException { // TODO Auto-generated method stub } private class LocalStateChangeListener implements StateChangeListener<AppSession> { private ServerAccSession session; LocalStateChangeListener(ServerAccSession session) { super(); this.session = session; } public void stateChanged(Enum oldState, Enum newState) { if (session.isStateless() && newState == IDLE) { session.release(); } if (log.isInfoEnabled()) { log.info("Application changed state from[" + oldState + "] to[" + newState + "]"); } } public void stateChanged(AppSession source, Enum oldState, Enum newState) { this.stateChanged(oldState, newState); } } }