--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+// Project
+#include <anna/diameter/helpers/base/functions.hpp>
+#include <anna/diameter/helpers/dcca/functions.hpp>
+#include <anna/http/Transport.hpp>
+
+// Process
+#include <MyCommunicator.hpp>
+
+
+void MyCommunicator::prepareAnswer(anna::diameter::codec::Message *answer, const anna::DataBlock &request) const throw() {
+ // Sequence values (hop-by-hop and end-to-end), session-id and subscription-id avps, are mirrored to the peer which sent the request.
+ // If user wants to test a specific answer without changing it, use send operations better than programming.
+ // Sequence substitution:
+ answer->setHopByHop(anna::diameter::codec::functions::getHopByHop(request));
+ answer->setEndToEnd(anna::diameter::codec::functions::getEndToEnd(request));
+
+ // Session-Id substitution:
+ try {
+ std::string sessionId = anna::diameter::helpers::base::functions::getSessionId(request);
+ LOGDEBUG(
+ std::string msg = "Extracted Session-Id: ";
+ msg += sessionId;
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+ answer->getAvp("Session-Id")->getUTF8String()->setValue(sessionId);
+ } catch(anna::RuntimeException &ex) {
+ ex.trace();
+ }
+
+ // Subscription-Id substitution: is not usual to carry Subscription-Id on answer messages, but if programmed answer have this information,
+ // then it will be adapted with the received data at request.
+ if(answer->countAvp("Subscription-Id") > 0) {
+ std::string msisdn = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(request, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
+ std::string imsi = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(request, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
+
+ if((msisdn != "") || (imsi != "")) { // Both request & answer have SID: replace answer one with the request information:
+ answer->removeAvp("Subscription-Id", 0 /* remove all */);
+ }
+
+ // Replacements:
+ if(msisdn != "") {
+ anna::diameter::codec::Avp *sid = answer->addAvp("Subscription-Id");
+ sid->addAvp("Subscription-Id-Type")->getEnumerated()->setValue(anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
+ sid->addAvp("Subscription-Id-Data")->getUTF8String()->setValue(msisdn);
+ }
+
+ if(imsi != "") {
+ anna::diameter::codec::Avp *sid = answer->addAvp("Subscription-Id"); // another
+ sid->addAvp("Subscription-Id-Type")->getEnumerated()->setValue(anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
+ sid->addAvp("Subscription-Id-Data")->getUTF8String()->setValue(imsi);
+ }
+ }
+}
+
+// HTTP
+void MyCommunicator::eventReceiveMessage(anna::comm::ClientSocket& clientSocket, const anna::comm::Message& message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
+}
+
+void MyCommunicator::eventBreakConnection(Server* server)
+throw() {
+ LOGMETHOD(anna::TraceMethod tm("MyCommunicator", "eventBreakConnection", ANNA_FILE_LOCATION));
+ terminate();
+ anna::comm::Communicator::eventBreakConnection(server);
+}
+
+void MyCommunicator::terminate()
+throw() {
+ if(hasRequestedStop() == true)
+ return;
+
+ requestStop();
+}
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef example_diameter_launcher_MyCommunicator_hpp
+#define example_diameter_launcher_MyCommunicator_hpp
+
+// Project
+#include <anna/core/core.hpp>
+#include <anna/comm/comm.hpp>
+#include <anna/diameter/codec/Message.hpp>
+
+
+class MyCommunicator : public anna::comm::Communicator {
+public:
+ MyCommunicator(const anna::comm::Communicator::WorkMode::_v acceptMode = anna::comm::Communicator::WorkMode::Single) : anna::comm::Communicator(acceptMode)
+ {;}
+
+ void prepareAnswer(anna::diameter::codec::Message *answer, const anna::DataBlock &request) const throw();
+ void terminate() throw();
+
+private:
+ using anna::comm::Communicator::eventBreakConnection;
+
+ void eventReceiveMessage(anna::comm::ClientSocket&, const anna::comm::Message&) throw(anna::RuntimeException);
+ void eventBreakConnection(Server* server) throw();
+};
+
+#endif
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef example_diameter_rxSimpleTest_MyDiameterEngine_hpp
+#define example_diameter_rxSimpleTest_MyDiameterEngine_hpp
+
+// Project
+#include <anna/diameter.comm/Engine.hpp>
+
+// Process
+#include <MyDiameterEntity.hpp>
+#include <MyLocalServer.hpp>
+
+// Standard
+#include <string>
+
+
+namespace anna {
+ namespace diameter {
+ namespace stack {
+ class Dictionary;
+ }
+ }
+}
+
+class MyDiameterEngine : public anna::diameter::comm::Engine {
+public:
+
+ MyDiameterEngine(const char *className, const anna::diameter::stack::Dictionary *baseProtocolDictionary) : Engine(className, baseProtocolDictionary) {;}
+
+// Default implementation is enough
+// void readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw() {;} // DPA is not replied
+// void readDWA(anna::DataBlock &dwa, const anna::DataBlock & dwr) throw() {;} // DWA is not replied
+
+private:
+ anna::Recycler<MyDiameterEntity> a_entitiesRecycler;
+
+ anna::diameter::comm::Entity* allocateEntity() throw() { return a_entitiesRecycler.create(); }
+
+ void releaseEntity(anna::diameter::comm::Entity* entity) throw() {
+ MyDiameterEntity* aux = static_cast <MyDiameterEntity*>(entity);
+ a_entitiesRecycler.release(aux);
+ }
+
+ anna::Recycler<MyLocalServer> a_localServersRecycler;
+
+ anna::diameter::comm::LocalServer* allocateLocalServer() throw() { return a_localServersRecycler.create(); }
+
+ void releaseLocalServer(anna::diameter::comm::LocalServer* localServer) throw() {
+ MyLocalServer* aux = static_cast <MyLocalServer*>(localServer);
+ a_localServersRecycler.release(aux);
+ }
+};
+
+#endif
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+// Project
+#include <anna/core/core.hpp>
+#include <anna/diameter/functions.hpp>
+#include <anna/time/functions.hpp>
+#include <anna/diameter.comm/Response.hpp>
+#include <anna/diameter.comm/ClientSession.hpp>
+#include <anna/diameter.comm/OriginHost.hpp>
+//#include <anna/diameter/helpers/base/functions.hpp>
+#include <anna/diameter/helpers/nas/defines.hpp>
+
+// Process
+#include <MyDiameterEngine.hpp>
+#include <MyDiameterEntity.hpp>
+#include <MyLocalServer.hpp>
+#include <rxSimpleTest.hpp>
+#include <anna/testing/TestManager.hpp>
+
+
+void MyDiameterEntity::eventRequestRetransmission(const anna::diameter::comm::ClientSession* clientSession, anna::diameter::comm::Message *request) throw() {
+
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyDiameterEntity", "eventRequestRetransmission", ANNA_FILE_LOCATION));
+
+ // Base class:
+ Entity::eventRequestRetransmission(clientSession, request); // warning trace
+
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(request->getBody());
+ LOGDEBUG
+ (
+ std::string msg = "Request retransmitted: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+}
+
+
+void MyDiameterEntity::eventRequest(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyDiameterEntity", "eventRequest", ANNA_FILE_LOCATION));
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
+ LOGDEBUG
+ (
+ std::string msg = "Request received: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+}
+
+void MyDiameterEntity::eventResponse(const anna::diameter::comm::Response &response)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyDiameterEntity", "eventResponse", ANNA_FILE_LOCATION));
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost *my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ anna::diameter::comm::ClassCode::_v code = response.getClassCode();
+ anna::diameter::comm::Response::ResultCode::_v result = response.getResultCode();
+ anna::diameter::comm::Message* request = const_cast<anna::diameter::comm::Message*>(response.getRequest());
+ const anna::DataBlock* message = response.getMessage();
+ const anna::diameter::comm::ClientSession *clientSession_c = static_cast<const anna::diameter::comm::ClientSession *>(response.getSession());
+ anna::diameter::comm::ClientSession *clientSession = const_cast<anna::diameter::comm::ClientSession *>(clientSession_c);
+ bool contextExpired = (result == anna::diameter::comm::Response::ResultCode::Timeout);
+ bool isUnavailable = (result == anna::diameter::comm::Response::ResultCode::DiameterUnavailable);
+ bool isOK = (result == anna::diameter::comm::Response::ResultCode::Success);
+
+ // CommandId:
+ anna::diameter::CommandId request_cid = request->getCommandId();
+ LOGDEBUG
+ (
+ std::string msg = "Response received for original diameter request: ";
+ msg += anna::diameter::functions::commandIdAsPairString(request_cid);
+ msg += " | Response: ";
+ msg += response.asString();
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+
+ if(isUnavailable) {
+ //if (isApplicationMessage)
+ LOGWARNING(anna::Logger::warning("Diameter entity unavailable for Diameter Request", ANNA_FILE_LOCATION));
+ }
+
+ if(contextExpired) {
+ //if (isApplicationMessage)
+ LOGWARNING(anna::Logger::warning("Context Expired for Diameter Request which was sent to the entity", ANNA_FILE_LOCATION));
+ }
+
+ if(isOK) {
+ LOGDEBUG(
+ std::string msg = "Received response for diameter message: ";
+ msg += anna::diameter::functions::commandIdAsPairString(request_cid);
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+
+ if(request_cid == anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) {
+ // Build AAR and send it:
+ anna::diameter::codec::Message aar;
+
+ // From file would be:
+ //aar.loadXML("./aar.xml");
+ aar.setApplicationId(anna::diameter::helpers::APPID__3GPP_Rx); // 16777236
+ aar.setId("AA-Request");
+
+ // Session-Id
+ Avp *sessionId = aar.addAvp("Session-Id");
+ sessionId->getUTF8String()->setValue("ocs3;1332774430;1;1332774430");
+
+ // Auth-Application-Id
+ Avp *authApplicationId = aar.addAvp("Auth-Application-Id");
+ authApplicationId->getUnsigned32()->setValue(16777236);
+
+ // Origin-Host
+ Avp *originHost = aar.addAvp("Origin-Host");
+ originHost->getDiameterIdentity()->setValue("thehost.theOriginRealm.com");
+
+ // Origin-Realm
+ Avp *originRealm = aar.addAvp("Origin-Realm");
+ originRealm->getDiameterIdentity()->setValue("theOriginRealm.com");
+
+ // Destination-Realm
+ Avp *destinationRealm = aar.addAvp("Destination-Realm");
+ destinationRealm->getDiameterIdentity()->setValue("theDestinationRealm.com");
+
+ // Suppported features:
+ Avp *supportedFeatures = aar.addAvp("Supported-Features");
+ supportedFeatures->addAvp("Vendor-Id")->getUnsigned32()->setValue(10415);
+ supportedFeatures->addAvp("Feature-List-ID")->getUnsigned32()->setValue(1);
+ supportedFeatures->addAvp("Feature-List")->getUnsigned32()->setValue(3);
+
+ anna::diameter::comm::Message *msg;
+
+ try {
+ msg = my_node->createCommMessage();
+ msg->setBody(aar.code());
+ /* response = NULL =*/clientSession->send(msg);
+ } catch(anna::RuntimeException &ex) {
+ ex.trace();
+ }
+
+ // release msg
+ my_node->releaseCommMessage(msg);
+ }
+ else if(request_cid == anna::diameter::helpers::nas::COMMANDID__AA_Request) {
+ // Decode
+ anna::diameter::codec::Message aaa;
+ try { aaa.decode(*message); } catch(anna::RuntimeException &ex) { ex.trace(); }
+
+ Avp *resultCode = aaa.getAvp("Result-Code");
+ int rc = resultCode->getUnsigned32()->getValue();
+
+ if (rc != 2001) exit(1);
+ else exit(0);
+ }
+ }
+}
+
+void MyDiameterEntity::eventUnknownResponse(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyDiameterEntity", "eventUnknownResponse", ANNA_FILE_LOCATION));
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
+ LOGDEBUG
+ (
+ std::string msg = "Out-of-context response received from entity: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+}
+
+void MyDiameterEntity::eventDPA(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyDiameterEntity", "eventDPA", ANNA_FILE_LOCATION));
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
+ LOGDEBUG
+ (
+ std::string msg = "Disconnect-Peer-Answer received from entity: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+}
+
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef example_diameter_rxSimpleTest_MyDiameterEntity_hpp
+#define example_diameter_rxSimpleTest_MyDiameterEntity_hpp
+
+// Project
+#include <anna/diameter.comm/Entity.hpp>
+
+namespace anna {
+ namespace diameter {
+ namespace codec {
+ class Engine;
+ }
+ }
+}
+
+class MyDiameterEntity : public anna::diameter::comm::Entity {
+
+ void eventRequestRetransmission(const anna::diameter::comm::ClientSession *, anna::diameter::comm::Message*) throw();
+ void eventResponse(const anna::diameter::comm::Response&) throw(anna::RuntimeException);
+ void eventRequest(anna::diameter::comm::ClientSession *, const anna::DataBlock&) throw(anna::RuntimeException);
+ void eventUnknownResponse(anna::diameter::comm::ClientSession *, const anna::DataBlock&) throw(anna::RuntimeException);
+ void eventDPA(anna::diameter::comm::ClientSession *, const anna::DataBlock&) throw(anna::RuntimeException);
+
+public:
+
+ MyDiameterEntity() {;}
+ virtual ~MyDiameterEntity() {;}
+};
+
+#endif
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+// Project
+#include <anna/core/core.hpp>
+#include <anna/diameter/functions.hpp>
+#include <anna/time/functions.hpp>
+#include <anna/diameter/codec/Engine.hpp>
+#include <anna/diameter.comm/Response.hpp>
+#include <anna/diameter.comm/ClientSession.hpp>
+#include <anna/diameter.comm/Server.hpp>
+#include <anna/diameter.comm/OriginHost.hpp>
+
+// Process
+#include <MyLocalServer.hpp>
+#include <MyDiameterEngine.hpp>
+#include <MyDiameterEntity.hpp>
+#include <rxSimpleTest.hpp>
+
+
+void MyLocalServer::eventRequest(anna::diameter::comm::ServerSession *serverSession, const anna::DataBlock &message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyLocalServer", "eventRequest", ANNA_FILE_LOCATION));
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost *my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ anna::diameter::codec::Engine *codecEngine = my_node->getCodecEngine();
+
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
+ LOGDEBUG
+ (
+ std::string msg = "Request received: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(serverSession->getAddress(), serverSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+
+ anna::diameter::codec::Message codecMsg;
+ anna::diameter::codec::Message codecAnsMsg;
+ anna::diameter::codec::Message *answer_message = (anna::diameter::codec::Message *)&codecAnsMsg;
+ my_app.getCommunicator()->prepareAnswer(answer_message, message);
+
+ anna::diameter::comm::Message *msg;
+ try {
+ msg = my_node->createCommMessage();
+ msg->setBody(answer_message->code());
+ /* response = NULL =*/serverSession->send(msg);
+ } catch(anna::RuntimeException &ex) {
+ ex.trace();
+ }
+
+ // release msg
+ my_node->releaseCommMessage(msg);
+}
+
+void MyLocalServer::eventResponse(const anna::diameter::comm::Response &response)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyLocalServer", "eventResponse", ANNA_FILE_LOCATION));
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ anna::diameter::comm::ClassCode::_v code = response.getClassCode();
+ anna::diameter::comm::Response::ResultCode::_v result = response.getResultCode();
+ anna::diameter::comm::Message* request = const_cast<anna::diameter::comm::Message*>(response.getRequest());
+ const anna::DataBlock* message = response.getMessage();
+ const anna::diameter::comm::ServerSession *serverSession = static_cast<const anna::diameter::comm::ServerSession *>(response.getSession());
+ bool contextExpired = (result == anna::diameter::comm::Response::ResultCode::Timeout);
+ bool isUnavailable = (result == anna::diameter::comm::Response::ResultCode::DiameterUnavailable);
+ bool isOK = (result == anna::diameter::comm::Response::ResultCode::Success);
+
+ // CommandId:
+ anna::diameter::CommandId request_cid = request->getCommandId();
+ LOGDEBUG
+ (
+ std::string msg = "Response received for original diameter request: ";
+ msg += anna::diameter::functions::commandIdAsPairString(request_cid);
+ msg += " | Response: ";
+ msg += response.asString();
+ msg += " | LocalServer: ";
+ msg += anna::functions::socketLiteralAsString(serverSession->getAddress(), serverSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+
+ if(isUnavailable) {
+ //if (isApplicationMessage)
+ LOGWARNING(anna::Logger::warning("Diameter client unavailable for Diameter Request", ANNA_FILE_LOCATION));
+ }
+
+ if(contextExpired) {
+ //if (isApplicationMessage)
+ LOGWARNING(anna::Logger::warning("Context Expired for Diameter Request which was sent to the client", ANNA_FILE_LOCATION));
+ }
+
+ if(isOK) {
+ LOGDEBUG(
+ std::string msg = "Received response for diameter message: ";
+ msg += anna::diameter::functions::commandIdAsPairString(request_cid);
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+ }
+}
+
+void MyLocalServer::eventUnknownResponse(anna::diameter::comm::ServerSession *serverSession, const anna::DataBlock &message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyLocalServer", "eventUnknownResponse", ANNA_FILE_LOCATION));
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost *my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
+ LOGDEBUG
+ (
+ std::string msg = "Out-of-context response received from client: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(serverSession->getAddress(), serverSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+}
+
+void MyLocalServer::eventDPA(anna::diameter::comm::ServerSession *serverSession, const anna::DataBlock &message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("rxSimpleTest::MyLocalServer", "eventDPA", ANNA_FILE_LOCATION));
+ // Performance stats:
+ RxSimpleTest& my_app = static_cast <RxSimpleTest&>(anna::app::functions::getApp());
+ anna::diameter::comm::OriginHost *my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
+ // CommandId:
+ anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
+ LOGDEBUG
+ (
+ std::string msg = "Disconnect-Peer-Answer response received from client: ";
+ msg += anna::diameter::functions::commandIdAsPairString(cid);
+ msg += " | DiameterServer: ";
+ msg += anna::functions::socketLiteralAsString(serverSession->getAddress(), serverSession->getPort());
+ msg += " | EventTime: ";
+ msg += anna::time::functions::currentTimeAsString();
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+}
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef example_diameter_rxSimpleTest_MyLocalServer_hpp
+#define example_diameter_rxSimpleTest_MyLocalServer_hpp
+
+// Project
+#include <anna/diameter.comm/LocalServer.hpp>
+
+
+namespace anna {
+ namespace diameter {
+ namespace codec {
+ class Engine;
+ }
+ }
+}
+
+class MyLocalServer : public anna::diameter::comm::LocalServer {
+
+ void eventResponse(const anna::diameter::comm::Response&) throw(anna::RuntimeException);
+ void eventRequest(anna::diameter::comm::ServerSession *, const anna::DataBlock&) throw(anna::RuntimeException);
+ void eventUnknownResponse(anna::diameter::comm::ServerSession *, const anna::DataBlock&) throw(anna::RuntimeException);
+ void eventDPA(anna::diameter::comm::ServerSession *, const anna::DataBlock&) throw(anna::RuntimeException);
+
+public:
+ virtual ~MyLocalServer() {;}
+};
+
+#endif
+
--- /dev/null
+dynamic/launcher/default
--- /dev/null
+anna_diameter.comm_static
+anna_diameter_static
+anna_time_static
+anna_statistics_static
+anna_timex_static
+anna_comm_static
+anna_app_static
+anna_xml_static
+anna_io_static
+anna_core_static
+pthread
+rt
+xml2
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+// Standard
+#include <string>
+
+// Project
+#include <anna/core/core.hpp>
+#include <anna/time/functions.hpp>
+
+// Process
+#include <rxSimpleTest.hpp>
+
+// To calculate the current working directory and get an absolute path for traces:
+#include <limits.h>
+#include <unistd.h>
+
+
+int main(int argc, const char** argv) {
+ anna::Logger::setLevel(anna::Logger::Debug);
+
+ // Current working directory and absolute trace path file:
+ std::string trace_file = "./rxSimpleTest.trace";
+
+ anna::Logger::initialize("rxSimpleTest", new TraceWriter(trace_file.c_str(), 2048000));
+ anna::time::functions::initialize(); // before application instantiation (it have a anna::time object)
+ anna::time::functions::setControlPoint(); // start control point (application lifetime)
+ RxSimpleTest app;
+
+ try {
+ app.start();
+ } catch(anna::Exception& ex) {
+ std::cout << ex.asString() << std::endl;
+ }
+
+ return 0;
+}
+
--- /dev/null
+Make release to fix executable symlink (if broken)
--- /dev/null
+../../../../build/Release/bin/anna_diameter_rxSimpleTest
\ No newline at end of file
--- /dev/null
+<dictionary name="DictionaryRx | Application-Id: 16777236">
+ <vendor name="IETF" code="0"/>
+ <vendor name="3GPP" code="10415"/>
+ <vendor name="ETSI" code="13019"/>
+ <avp name="User-Name" code="1" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="Framed-IP-Address" code="8" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Class" code="25" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Session-Timeout" code="27" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Called-Station-Id" code="30" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Proxy-State" code="33" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Acct-Session-Id" code="44" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Acct-Multi-Session-Id" code="50" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="Event-Timestamp" code="55" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Time"/>
+ </avp>
+ <avp name="Acct-Interim-Interval" code="85" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Framed-IPv6-Prefix" code="97" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Host-IP-Address" code="257" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Address"/>
+ </avp>
+ <avp name="Auth-Application-Id" code="258" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Acct-Application-Id" code="259" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Vendor-Specific-Application-Id" code="260" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Vendor-Id" type="Mandatory" qual="1*"/>
+ <avprule id="Auth-Application-Id" type="Optional"/>
+ <avprule id="Acct-Application-Id" type="Optional"/>
+ </grouped>
+ </avp>
+ <avp name="Redirect-Host-Usage" code="261" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-6">
+ <label data="0" alias="DONT_CACHE"/>
+ <label data="1" alias="ALL_SESSION"/>
+ <label data="2" alias="ALL_REALM"/>
+ <label data="3" alias="REALM_AND_APPLICATION"/>
+ <label data="4" alias="ALL_APPLICATION"/>
+ <label data="5" alias="ALL_HOST"/>
+ <label data="6" alias="ALL_USER"/>
+ </single>
+ </avp>
+ <avp name="Redirect-Max-Cache-Time" code="262" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Session-Id" code="263" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="Origin-Host" code="264" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Supported-Vendor-Id" code="265" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Vendor-Id" code="266" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Firmware-Revision" code="267" may-encrypt="yes" v-bit="mustnot" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Result-Code" code="268" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32">
+ <label data="1001" alias="DIAMETER_MULTI_ROUND_AUTH"/>
+ <label data="2001" alias="DIAMETER_SUCCESS"/>
+ <label data="2002" alias="DIAMETER_LIMITED_SUCCESS"/>
+ <label data="3001" alias="DIAMETER_COMMAND_UNSUPPORTED"/>
+ <label data="3002" alias="DIAMETER_UNABLE_TO_DELIVER"/>
+ <label data="3003" alias="DIAMETER_REALM_NOT_SERVED"/>
+ <label data="3004" alias="DIAMETER_TOO_BUSY"/>
+ <label data="3005" alias="DIAMETER_LOOP_DETECTED"/>
+ <label data="3006" alias="DIAMETER_REDIRECT_INDICATION"/>
+ <label data="3007" alias="DIAMETER_APPLICATION_UNSUPPORTED"/>
+ <label data="3008" alias="DIAMETER_INVALID_HDR_BITS"/>
+ <label data="3009" alias="DIAMETER_INVALID_AVP_BITS"/>
+ <label data="3010" alias="DIAMETER_UNKNOWN_PEER"/>
+ <label data="4001" alias="DIAMETER_AUTHENTICATION_REJECTED"/>
+ <label data="4002" alias="DIAMETER_OUT_OF_SPACE"/>
+ <label data="4003" alias="DIAMETER_ELECTION_LOST"/>
+ <label data="4241" alias="DIAMETER_NO_AVAILABLE_POLICY_COUNTERS"/>
+ <label data="5001" alias="DIAMETER_AVP_UNSUPPORTED"/>
+ <label data="5002" alias="DIAMETER_UNKNOWN_SESSION_ID"/>
+ <label data="5003" alias="DIAMETER_AUTHORIZATION_REJECTED"/>
+ <label data="5004" alias="DIAMETER_INVALID_AVP_VALUE"/>
+ <label data="5005" alias="DIAMETER_MISSING_AVP"/>
+ <label data="5006" alias="DIAMETER_RESOURCES_EXCEEDED"/>
+ <label data="5007" alias="DIAMETER_CONTRADICTING_AVPS"/>
+ <label data="5008" alias="DIAMETER_AVP_NOT_ALLOWED"/>
+ <label data="5009" alias="DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"/>
+ <label data="5010" alias="DIAMETER_NO_COMMON_APPLICATION"/>
+ <label data="5011" alias="DIAMETER_UNSUPPORTED_VERSION"/>
+ <label data="5012" alias="DIAMETER_UNABLE_TO_COMPLY"/>
+ <label data="5013" alias="DIAMETER_INVALID_BIT_IN_HEADER"/>
+ <label data="5014" alias="DIAMETER_INVALID_AVP_LENGTH"/>
+ <label data="5015" alias="DIAMETER_INVALID_MESSAGE_LENGTH"/>
+ <label data="5016" alias="DIAMETER_INVALID_AVP_BIT_COMBO"/>
+ <label data="5017" alias="DIAMETER_NO_COMMON_SECURITY"/>
+ <label data="5030" alias="DIAMETER_USER_UNKNOWN"/>
+ <label data="5063" alias="REQUESTED_SERVICE_NOT_AUTHORIZED"/>
+ <label data="5065" alias="IP_CAN_SESSION_NOT_AVAILABLE"/>
+ </single>
+ </avp>
+ <avp name="Product-Name" code="269" may-encrypt="yes" v-bit="mustnot" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="Session-Binding" code="270" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Session-Server-Failover" code="271" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-3">
+ <label data="0" alias="REFUSE_SERVICE"/>
+ <label data="1" alias="TRY_AGAIN"/>
+ <label data="2" alias="ALLOW_SERVICE"/>
+ <label data="3" alias="TRY_AGAIN_ALLOW_SERVICE"/>
+ </single>
+ </avp>
+ <avp name="Multi-Round-Time-Out" code="272" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Disconnect-Cause" code="273" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-2">
+ <label data="0" alias="REBOOTING"/>
+ <label data="1" alias="BUSY"/>
+ <label data="2" alias="DO_NOT_WANT_TO_TALK_TO_YOU"/>
+ </single>
+ </avp>
+ <avp name="Auth-Request-Type" code="274" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="1-3">
+ <label data="1" alias="AUTHENTICATE_ONLY"/>
+ <label data="2" alias="AUTHORIZE_ONLY"/>
+ <label data="3" alias="AUTHORIZE_AUTHENTICATE"/>
+ </single>
+ </avp>
+ <avp name="Auth-Grace-Period" code="276" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Auth-Session-State" code="277" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="STATE_MAINTAINED"/>
+ <label data="1" alias="NO_STATE_MAINTAINED"/>
+ </single>
+ </avp>
+ <avp name="Origin-State-Id" code="278" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Failed-AVP" code="279" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="AVP" type="Mandatory" qual="1*"/>
+ </grouped>
+ </avp>
+ <avp name="Proxy-Host" code="280" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Error-Message" code="281" may-encrypt="yes" v-bit="mustnot" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="Route-Record" code="282" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Destination-Realm" code="283" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Proxy-Info" code="284" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Proxy-Host" type="Mandatory"/>
+ <avprule id="Proxy-State" type="Mandatory"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </grouped>
+ </avp>
+ <avp name="Re-Auth-Request-Type" code="285" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="AUTHORIZE_ONLY"/>
+ <label data="1" alias="AUTHORIZE_AUTHENTICATE"/>
+ </single>
+ </avp>
+ <avp name="Accounting-Sub-Session-Id" code="287" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned64"/>
+ </avp>
+ <avp name="Redirect-Host" code="292" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterURI"/>
+ </avp>
+ <avp name="Destination-Host" code="293" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Error-Reporting-Host" code="294" may-encrypt="yes" v-bit="mustnot" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Termination-Cause" code="295" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="1-8">
+ <label data="1" alias="LOGOUT"/>
+ <label data="2" alias="SERVICE_NOT_PROVIDED"/>
+ <label data="3" alias="BAD_ANSWER"/>
+ <label data="4" alias="ADMINISTRATIVE"/>
+ <label data="5" alias="LINK_BROKEN"/>
+ <label data="6" alias="AUTH_EXPIRED"/>
+ <label data="7" alias="USER_MOVED"/>
+ <label data="8" alias="SESSION_TIMEOUT"/>
+ </single>
+ </avp>
+ <avp name="Origin-Realm" code="296" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="DiameterIdentity"/>
+ </avp>
+ <avp name="Experimental-Result" code="297" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Vendor-Id" type="Mandatory"/>
+ <avprule id="Experimental-Result-Code" type="Mandatory"/>
+ </grouped>
+ </avp>
+ <avp name="Experimental-Result-Code" code="298" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Inband-Security-Id" code="299" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="E2E-Sequence" code="300" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="AVP" type="Mandatory" qual="2*"/>
+ </grouped>
+ </avp>
+ <avp name="Subscription-Id" code="443" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Subscription-Id-Type" type="Mandatory"/>
+ <avprule id="Subscription-Id-Data" type="Mandatory"/>
+ </grouped>
+ </avp>
+ <avp name="Subscription-Id-Data" code="444" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="Subscription-Id-Type" code="450" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-4">
+ <label data="0" alias="END_USER_E164"/>
+ <label data="1" alias="END_USER_IMSI"/>
+ <label data="2" alias="END_USER_SIP_URI"/>
+ <label data="3" alias="END_USER_NAI"/>
+ <label data="4" alias="END_USER_PRIVATE"/>
+ </single>
+ </avp>
+ <avp name="Accounting-Record-Type" code="480" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="1-4">
+ <label data="1" alias="EVENT_RECORD"/>
+ <label data="2" alias="START_RECORD"/>
+ <label data="3" alias="INTERIM_RECORD"/>
+ <label data="4" alias="STOP_RECORD"/>
+ </single>
+ </avp>
+ <avp name="Accounting-Realtime-Required" code="483" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="1-3">
+ <label data="1" alias="DELIVER_AND_GRANT"/>
+ <label data="2" alias="GRANT_AND_STORE"/>
+ <label data="3" alias="GRANT_AND_LOSE"/>
+ </single>
+ </avp>
+ <avp name="Accounting-Record-Number" code="485" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="3GPP-SGSN-MCC-MNC" code="18" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="UTF8String"/>
+ </avp>
+ <avp name="3GPP-User-Location-Info" code="22" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="3GPP-MS-TimeZone" code="23" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Abort-Cause" code="500" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-4">
+ <label data="0" alias="BEARER_RELEASED"/>
+ <label data="1" alias="INSUFFICIENT_SERVER_RESOURCES"/>
+ <label data="2" alias="INSUFFICIENT_BEARER_RESOURCES"/>
+ <label data="3" alias="PS_TO_CS_HANDOVER"/>
+ <label data="4" alias="SPONSORED_DATA_CONNECTIVITY_DISALLOWED"/>
+ </single>
+ </avp>
+ <avp name="AF-Application-Identifier" code="504" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="AF-Charging-Identifier" code="505" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Flow-Description" code="507" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="IPFilterRule"/>
+ </avp>
+ <avp name="Flow-Number" code="509" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Flows" code="510" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Media-Component-Number" type="Mandatory"/>
+ <avprule id="Flow-Number" type="Optional" qual="*"/>
+ </grouped>
+ </avp>
+ <avp name="Flow-Status" code="511" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-4">
+ <label data="0" alias="ENABLED-UPLINK"/>
+ <label data="1" alias="ENABLED-DOWNLINK"/>
+ <label data="2" alias="ENABLED"/>
+ <label data="3" alias="DISABLED"/>
+ <label data="4" alias="REMOVED"/>
+ </single>
+ </avp>
+ <avp name="Flow-Usage" code="512" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-2">
+ <label data="0" alias="NO_INFORMATION"/>
+ <label data="1" alias="RTCP"/>
+ <label data="2" alias="AF_SIGNALLING"/>
+ </single>
+ </avp>
+ <avp name="Specific-Action" code="513" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="1-4,6-14">
+ <label data="1" alias="CHARGING_CORRELATION_EXCHANGE"/>
+ <label data="2" alias="INDICATION_OF_LOSS_OF_BEARER"/>
+ <label data="3" alias="INDICATION_OF_RECOVERY_OF_BEARER"/>
+ <label data="4" alias="INDICATION_OF_RELEASE_OF_BEARER"/>
+ <label data="6" alias="IP-CAN_CHANGE"/>
+ <label data="7" alias="INDICATION_OF_OUT_OF_CREDIT"/>
+ <label data="8" alias="INDICATION_OF_SUCCESSFUL_RESOURCES_ALLOCATION"/>
+ <label data="9" alias="INDICATION_OF_FAILED_RESOURCES_ALLOCATION"/>
+ <label data="10" alias="INDICATION_OF_LIMITED_PCC_DEPLOYMENT"/>
+ <label data="11" alias="USAGE_REPORT"/>
+ <label data="12" alias="ACCESS_NETWORK_INFO_REPORT"/>
+ <label data="13" alias="INDICATION_OF_RECOVERY_FROM_LIMITED_PCC_DEPLOYMENT"/>
+ <label data="14" alias="INDICATION_OF_ACCESS_NETWORK_INFO_REPORTING_FAILURE"/>
+ </single>
+ </avp>
+ <avp name="Max-Requested-Bandwidth-DL" code="515" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Max-Requested-Bandwidth-UL" code="516" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Media-Component-Description" code="517" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Media-Component-Number" type="Mandatory"/>
+ <avprule id="Media-Sub-Component" type="Optional" qual="*"/>
+ <avprule id="AF-Application-Identifier" type="Optional"/>
+ <avprule id="Media-Type" type="Optional"/>
+ <avprule id="Max-Requested-Bandwidth-UL" type="Optional"/>
+ <avprule id="Max-Requested-Bandwidth-DL" type="Optional"/>
+ <avprule id="Min-Requested-Bandwidth-UL" type="Optional"/>
+ <avprule id="Min-Requested-Bandwidth-DL" type="Optional"/>
+ <avprule id="Flow-Status" type="Optional"/>
+ <avprule id="Reservation-Priority" type="Optional"/>
+ <avprule id="RS-Bandwidth" type="Optional"/>
+ <avprule id="RR-Bandwidth" type="Optional"/>
+ <avprule id="Codec-Data" type="Optional" qual="*"/>
+ </grouped>
+ </avp>
+ <avp name="Media-Component-Number" code="518" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Media-Sub-Component" code="519" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <grouped>
+ <avprule id="Flow-Number" type="Mandatory"/>
+ <avprule id="Flow-Description" type="Optional" qual="0*2"/>
+ <avprule id="Flow-Status" type="Optional"/>
+ <avprule id="Flow-Usage" type="Optional"/>
+ <avprule id="Max-Requested-Bandwidth-UL" type="Optional"/>
+ <avprule id="Max-Requested-Bandwidth-DL" type="Optional"/>
+ </grouped>
+ </avp>
+ <avp name="Media-Type" code="520" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-6">
+ <label data="0" alias="OTHER"/>
+ <label data="1" alias="VIDEO"/>
+ <label data="2" alias="DATA"/>
+ <label data="3" alias="APPLICATION"/>
+ <label data="4" alias="CONTROL"/>
+ <label data="5" alias="TEXT"/>
+ <label data="6" alias="MESSAGE"/>
+ </single>
+ </avp>
+ <avp name="RR-Bandwidth" code="521" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="RS-Bandwidth" code="522" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="SIP-Forking-Indication" code="523" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="SINGLE_DIALOGUE"/>
+ <label data="1" alias="SEVERAL_DIALOGUES"/>
+ </single>
+ </avp>
+ <avp name="Codec-Data" code="524" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Service-URN" code="525" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Service-Info-Status" code="527" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="must" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="FINAL_SERVICE_INFORMATION"/>
+ <label data="1" alias="PRELIMINARY_SERVICE_INFORMATION"/>
+ </single>
+ </avp>
+ <avp name="MPS-Identifier" code="528" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="AF-Signalling-Protocol" code="529" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="NO_INFORMATION"/>
+ <label data="1" alias="SIP"/>
+ </single>
+ </avp>
+ <avp name="Rx-Request-Type" code="533" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="INITIAL_REQUEST"/>
+ <label data="1" alias="UPDATE_REQUEST"/>
+ </single>
+ </avp>
+ <avp name="Min-Requested-Bandwidth-DL" code="534" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Min-Requested-Bandwidth-UL" code="535" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Required-Access-Info" code="536" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-1">
+ <label data="0" alias="USER_LOCATION"/>
+ <label data="1" alias="MS_TIME_ZONE"/>
+ </single>
+ </avp>
+ <avp name="IP-Domain-Id" code="537" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="OctetString"/>
+ </avp>
+ <avp name="Supported-Features" code="628" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="may" p-bit="mustnot">
+ <grouped>
+ <avprule id="Vendor-Id" type="Mandatory"/>
+ <avprule id="Feature-List-ID" type="Mandatory"/>
+ <avprule id="Feature-List" type="Mandatory"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </grouped>
+ </avp>
+ <avp name="Feature-List-ID" code="629" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Feature-List" code="630" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="User-Location-Info-Time" code="2812" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Time"/>
+ </avp>
+ <avp name="NetLoc-Access-Support" code="2824" vendor-name="3GPP" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Unsigned32"/>
+ </avp>
+ <avp name="Reservation-Priority" code="458" vendor-name="ETSI" may-encrypt="yes" v-bit="must" m-bit="mustnot" p-bit="mustnot">
+ <single format-name="Enumerated" enum="0-15">
+ <label data="0" alias="DEFAULT"/>
+ <label data="1" alias="PRIORITY-ONE"/>
+ <label data="2" alias="PRIORITY-TWO"/>
+ <label data="3" alias="PRIORITY-THREE"/>
+ <label data="4" alias="PRIORITY-FOUR"/>
+ <label data="5" alias="PRIORITY-FIVE"/>
+ <label data="6" alias="PRIORITY-SIX"/>
+ <label data="7" alias="PRIORITY-SEVEN"/>
+ <label data="8" alias="PRIORITY-EIGHT"/>
+ <label data="9" alias="PRIORITY-NINE"/>
+ <label data="10" alias="PRIORITY-TEN"/>
+ <label data="11" alias="PRIORITY-ELEVEN"/>
+ <label data="12" alias="PRIORITY-TWELVE"/>
+ <label data="13" alias="PRIORITY-THIRTEEN"/>
+ <label data="14" alias="PRIORITY-FOURTEEN"/>
+ <label data="15" alias="PRIORITY-FIFTEEN"/>
+ </single>
+ </avp>
+ <command name="CER" code="257" type="Request">
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Host-IP-Address" type="Mandatory" qual="1*"/>
+ <avprule id="Vendor-Id" type="Mandatory"/>
+ <avprule id="Product-Name" type="Mandatory"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Supported-Vendor-Id" type="Optional" qual="*"/>
+ <avprule id="Auth-Application-Id" type="Optional" qual="*"/>
+ <avprule id="Inband-Security-Id" type="Optional" qual="*"/>
+ <avprule id="Acct-Application-Id" type="Optional" qual="*"/>
+ <avprule id="Vendor-Specific-Application-Id" type="Optional" qual="*"/>
+ <avprule id="Firmware-Revision" type="Optional"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="CEA" code="257" type="Answer">
+ <avprule id="Result-Code" type="Mandatory"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Host-IP-Address" type="Mandatory" qual="1*"/>
+ <avprule id="Vendor-Id" type="Mandatory"/>
+ <avprule id="Product-Name" type="Mandatory"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Error-Message" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ <avprule id="Supported-Vendor-Id" type="Optional" qual="*"/>
+ <avprule id="Auth-Application-Id" type="Optional" qual="*"/>
+ <avprule id="Inband-Security-Id" type="Optional" qual="*"/>
+ <avprule id="Acct-Application-Id" type="Optional" qual="*"/>
+ <avprule id="Vendor-Specific-Application-Id" type="Optional" qual="*"/>
+ <avprule id="Firmware-Revision" type="Optional"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="RA-Request" code="258" type="Request">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Destination-Realm" type="Mandatory"/>
+ <avprule id="Destination-Host" type="Mandatory"/>
+ <avprule id="Auth-Application-Id" type="Mandatory"/>
+ <avprule id="Specific-Action" type="Mandatory" qual="*"/>
+ <avprule id="Flows" type="Optional" qual="*"/>
+ <avprule id="Abort-Cause" type="Optional"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="Route-Record" type="Optional" qual="*"/>
+ <avprule id="3GPP-MS-TimeZone" type="Optional"/>
+ <avprule id="3GPP-User-Location-Info" type="Optional"/>
+ <avprule id="3GPP-SGSN-MCC-MNC" type="Optional"/>
+ <avprule id="NetLoc-Access-Support" type="Optional"/>
+ <avprule id="User-Location-Info-Time" type="Optional"/>
+ </command>
+ <command name="RA-Answer" code="258" type="Answer">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Result-Code" type="Optional"/>
+ <avprule id="Experimental-Result" type="Optional"/>
+ <avprule id="Media-Component-Description" type="Optional" qual="*"/>
+ <avprule id="Service-URN" type="Optional"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Class" type="Optional" qual="*"/>
+ <avprule id="Error-Message" type="Optional"/>
+ <avprule id="Error-Reporting-Host" type="Optional"/>
+ <avprule id="Redirect-Host" type="Optional" qual="*"/>
+ <avprule id="Redirect-Host-Usage" type="Optional"/>
+ <avprule id="Redirect-Max-Cache-Time" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="AA-Request" code="265" type="Request">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Auth-Application-Id" type="Mandatory"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Destination-Realm" type="Mandatory"/>
+ <avprule id="Destination-Host" type="Optional"/>
+ <avprule id="IP-Domain-Id" type="Optional"/>
+ <avprule id="AF-Application-Identifier" type="Optional"/>
+ <avprule id="Media-Component-Description" type="Optional" qual="*"/>
+ <avprule id="Service-Info-Status" type="Optional"/>
+ <avprule id="AF-Charging-Identifier" type="Optional"/>
+ <avprule id="SIP-Forking-Indication" type="Optional"/>
+ <avprule id="Specific-Action" type="Optional" qual="*"/>
+ <avprule id="Subscription-Id" type="Optional" qual="*"/>
+ <avprule id="Supported-Features" type="Optional" qual="*"/>
+ <avprule id="Reservation-Priority" type="Optional"/>
+ <avprule id="Framed-IP-Address" type="Optional"/>
+ <avprule id="Framed-IPv6-Prefix" type="Optional"/>
+ <avprule id="Called-Station-Id" type="Optional"/>
+ <avprule id="Service-URN" type="Optional"/>
+ <avprule id="MPS-Identifier" type="Optional"/>
+ <avprule id="Rx-Request-Type" type="Optional"/>
+ <avprule id="Required-Access-Info" type="Optional" qual="*"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="Route-Record" type="Optional" qual="*"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="AA-Answer" code="265" type="Answer">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Auth-Application-Id" type="Mandatory"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Result-Code" type="Optional"/>
+ <avprule id="Experimental-Result" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Supported-Features" type="Optional" qual="*"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ </command>
+ <command name="ACR" code="271" type="Request">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Destination-Realm" type="Mandatory"/>
+ <avprule id="Accounting-Record-Type" type="Mandatory"/>
+ <avprule id="Accounting-Record-Number" type="Mandatory"/>
+ <avprule id="Acct-Application-Id" type="Optional"/>
+ <avprule id="Vendor-Specific-Application-Id" type="Optional"/>
+ <avprule id="User-Name" type="Optional"/>
+ <avprule id="Accounting-Sub-Session-Id" type="Optional"/>
+ <avprule id="Acct-Session-Id" type="Optional"/>
+ <avprule id="Acct-Multi-Session-Id" type="Optional"/>
+ <avprule id="Acct-Interim-Interval" type="Optional"/>
+ <avprule id="Accounting-Realtime-Required" type="Optional"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Event-Timestamp" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="Route-Record" type="Optional" qual="*"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="ACA" code="271" type="Answer">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Result-Code" type="Mandatory"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Accounting-Record-Type" type="Mandatory"/>
+ <avprule id="Accounting-Record-Number" type="Mandatory"/>
+ <avprule id="Acct-Application-Id" type="Optional"/>
+ <avprule id="Vendor-Specific-Application-Id" type="Optional"/>
+ <avprule id="User-Name" type="Optional"/>
+ <avprule id="Accounting-Sub-Session-Id" type="Optional"/>
+ <avprule id="Acct-Session-Id" type="Optional"/>
+ <avprule id="Acct-Multi-Session-Id" type="Optional"/>
+ <avprule id="Error-Reporting-Host" type="Optional"/>
+ <avprule id="Acct-Interim-Interval" type="Optional"/>
+ <avprule id="Accounting-Realtime-Required" type="Optional"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Event-Timestamp" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="AS-Request" code="274" type="Request">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Destination-Realm" type="Mandatory"/>
+ <avprule id="Destination-Host" type="Mandatory"/>
+ <avprule id="Auth-Application-Id" type="Mandatory"/>
+ <avprule id="Abort-Cause" type="Mandatory"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="Route-Record" type="Optional" qual="*"/>
+ </command>
+ <command name="AS-Answer" code="274" type="Answer">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Result-Code" type="Optional"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Error-Message" type="Optional"/>
+ <avprule id="Error-Reporting-Host" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ <avprule id="Redirect-Host" type="Optional" qual="*"/>
+ <avprule id="Redirect-Host-Usage" type="Optional"/>
+ <avprule id="Redirect-Max-Cache-Time" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="ST-Request" code="275" type="Request">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Destination-Realm" type="Mandatory"/>
+ <avprule id="Auth-Application-Id" type="Mandatory"/>
+ <avprule id="Termination-Cause" type="Mandatory"/>
+ <avprule id="Destination-Host" type="Optional"/>
+ <avprule id="Required-Access-Info" type="Optional" qual="*"/>
+ <avprule id="Class" type="Optional" qual="*"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="Route-Record" type="Optional" qual="*"/>
+ <avprule id="AVP" type="Optional" qual="*"/>
+ </command>
+ <command name="ST-Answer" code="275" type="Answer">
+ <avprule id="Session-Id" type="Fixed"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Result-Code" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ <avprule id="Proxy-Info" type="Optional" qual="*"/>
+ <avprule id="3GPP-MS-TimeZone" type="Optional"/>
+ <avprule id="3GPP-User-Location-Info" type="Optional"/>
+ <avprule id="3GPP-SGSN-MCC-MNC" type="Optional"/>
+ <avprule id="NetLoc-Access-Support" type="Optional"/>
+ <avprule id="User-Location-Info-Time" type="Optional"/>
+ </command>
+ <command name="DWR" code="280" type="Request">
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ </command>
+ <command name="DWA" code="280" type="Answer">
+ <avprule id="Result-Code" type="Mandatory"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Error-Message" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ <avprule id="Origin-State-Id" type="Optional"/>
+ </command>
+ <command name="DPR" code="282" type="Request">
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Disconnect-Cause" type="Mandatory"/>
+ </command>
+ <command name="DPA" code="282" type="Answer">
+ <avprule id="Result-Code" type="Mandatory"/>
+ <avprule id="Origin-Host" type="Mandatory"/>
+ <avprule id="Origin-Realm" type="Mandatory"/>
+ <avprule id="Error-Message" type="Optional"/>
+ <avprule id="Failed-AVP" type="Optional" qual="*"/>
+ </command>
+</dictionary>
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+// Standard
+#include <sstream> // std::istringstream
+#include <iostream> // std::cout
+#include <math.h> // ceil
+#include <climits>
+#include <unistd.h> // chdir
+//#include <regex> TODO: use this from gcc4.9.0: http://stackoverflow.com/questions/8060025/is-this-c11-regex-error-me-or-the-compiler
+#include <stdio.h>
+
+// Project
+#include <anna/timex/Engine.hpp>
+#include <anna/statistics/Engine.hpp>
+#include <anna/diameter/codec/functions.hpp>
+#include <anna/diameter/codec/Engine.hpp>
+#include <anna/diameter/codec/EngineManager.hpp>
+#include <anna/diameter/stack/Engine.hpp>
+#include <anna/diameter/helpers/base/functions.hpp>
+#include <anna/time/functions.hpp>
+#include <anna/diameter.comm/ApplicationMessageOamModule.hpp>
+#include <anna/testing/defines.hpp>
+#include <anna/xml/xml.hpp>
+#include <anna/diameter.comm/OriginHost.hpp>
+#include <anna/diameter.comm/OriginHostManager.hpp>
+
+// Process
+#include <rxSimpleTest.hpp>
+#include <MyDiameterEngine.hpp>
+
+RxSimpleTest::RxSimpleTest() : anna::comm::Application("rxSimpleTest", "RxSimpleTest", "1.1"), a_communicator(NULL) {
+ a_timeEngine = NULL;
+ a_admlMinResolution = 2 * anna::timex::Engine::minResolution; // 2*10 = 20 ms; 1000/20 = 50 ticks per second;
+ //a_admlMinResolution = (anna::Millisecond)100;
+ a_workingNode = NULL;
+}
+
+void RxSimpleTest::startService() throw(anna::RuntimeException) {
+
+ // Stacks
+ anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate();
+ anna::diameter::stack::Dictionary *d;
+ const anna::diameter::stack::Dictionary *bpd = NULL; // base protocol dictionary
+
+ // Codec engine manager:
+ anna::diameter::codec::EngineManager &em = anna::diameter::codec::EngineManager::instantiate();
+ anna::diameter::codec::Engine *ce;
+
+ ///////////////////////////////////////////
+ // APPLICATION MESSAGE OAM MODULE SCOPES //
+ ///////////////////////////////////////////
+ // We will register a scope per stack id registered. The counters will be dynamically registered at count method.
+ anna::diameter::comm::ApplicationMessageOamModule & appMsgOamModule = anna::diameter::comm::ApplicationMessageOamModule::instantiate();
+ appMsgOamModule.enableCounters(); // this special module is disabled by default (the only)
+ int scope_id = 3;
+ unsigned int id_value = anna::diameter::helpers::APPID__3GPP_Rx; // 16777236
+
+ try {
+ d = stackEngine.createDictionary(id_value, "./dictionaryRx.xml");
+ LOGDEBUG(anna::Logger::debug(anna::functions::asString("Created dictionary (%p) for stack id %llu", d, id_value), ANNA_FILE_LOCATION));
+
+ // OAM module for counters:
+ appMsgOamModule.createStackCounterScope(scope_id, id_value /* application-id */);
+
+ } catch(anna::RuntimeException &ex) {
+ //_exit(ex.asString());
+ throw ex;
+ }
+
+ bpd = d; // base protocol dictionary in case of monostack
+
+ // Create codec engine and register it in the codec engine manager:
+ std::string codecEngineName = anna::functions::asString("CodecEngineForStackId_%llu", id_value);
+ ce = new anna::diameter::codec::Engine(codecEngineName.c_str(), d);
+ em.registerCodecEngine(id_value, ce);
+
+ // Codec engine configuration:
+
+ // Validation mode: BeforeEncoding, AfterDecoding, Always, Never
+ ce->setValidationMode(anna::diameter::codec::Engine::ValidationMode::AfterDecoding);
+
+ // Validation depth: Complete, FirstError
+ ce->setValidationDepth(anna::diameter::codec::Engine::ValidationDepth::FirstError);
+
+ // Fix mode: BeforeEncoding, AfterDecoding, Always, Never
+ ce->setFixMode(anna::diameter::codec::Engine::FixMode::BeforeEncoding);
+
+ // Ignore validation flags:
+ ce->ignoreFlagsOnValidation(true);
+
+ // Show loaded stacks:
+ std::cout << "Stacks currently loaded:" << std::endl;
+ std::cout << anna::functions::tab(stackEngine.asString(false /* light */)) << std::endl;
+
+ // REALMS:
+ unsigned int applicationId = id_value;
+ if (!stackEngine.getDictionary(applicationId)) {
+ std::string msg = anna::functions::asString("Cannot found a registered stack id with the value of applicationId provided: %u", applicationId);
+ throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
+ }
+
+ // Engine time measures checking & assignment:
+ anna::Millisecond allowedInactivityTimeMs(90000);
+ anna::Millisecond tcpConnectDelayMs(200);
+ anna::Millisecond answersTimeoutMs(10000);
+ anna::Millisecond ceaTimeoutMs(10000);
+ anna::Millisecond watchdogPeriodMs(30000);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Diameter communication engine:
+ std::string originHostRealm = "nodeHostRealm";
+ std::string originHostName = "afNodeHostname."; originHostName += originHostRealm; originHostName += ".com";
+ std::string commEngineName = originHostName + "_DiameterCommEngine";
+ MyDiameterEngine *commEngine = new MyDiameterEngine(commEngineName.c_str(), bpd);
+ commEngine->setAutoBind(false); // allow to create client-sessions without binding them, in order to set timeouts.
+ commEngine->setMaxConnectionDelay(tcpConnectDelayMs);
+ commEngine->setWatchdogPeriod(watchdogPeriodMs);
+ commEngine->setOriginHostName(originHostName);
+ commEngine->setOriginRealmName(originHostRealm);
+
+ // Origin host node:
+ a_workingNode = new anna::diameter::comm::OriginHost((anna::diameter::comm::Engine*)commEngine, applicationId);
+ // a_workingNode->setRequestRetransmissions(0);
+
+ // Diameter entity:
+ commEngine->setNumberOfClientSessionsPerServer(1);
+ //commEngine->setClientCERandDWR("./cer.xml", "./dwr.xml");
+ commEngine->setClientCERandDWR();
+
+ // Register one entity for this engine:
+ a_workingNode->createEntity("localhost:3868", ceaTimeoutMs, answersTimeoutMs);
+ a_workingNode->getEntity()->bind();
+
+ // Diameter server:
+ //a_workingNode->createDiameterServer("localhost:3869", 1, allowedInactivityTimeMs, answersTimeoutMs, "./cea.xml");
+
+ commEngine->lazyInitialize();
+
+ // Node and Codec Engine registration ///////////////////////////////////////////////////////
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ ohm.registerOriginHost(originHostName, a_workingNode);
+}
+
+anna::diameter::comm::OriginHost *RxSimpleTest::getOriginHost(const std::string &name) const throw(anna::RuntimeException) {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ anna::diameter::comm::OriginHost *result = ohm.getOriginHost(name);
+
+ if (!result)
+ throw anna::RuntimeException(anna::functions::asString("There is no origin host registered as '%s' (set Origin-Host avp correctly or force a specific host with 'node' operation)", name.c_str()), ANNA_FILE_LOCATION);
+
+ return result;
+}
+
+MyDiameterEntity *RxSimpleTest::getEntity() const throw(anna::RuntimeException) {
+ MyDiameterEntity *result = (MyDiameterEntity *)(a_workingNode->getEntity());
+ if (!result)
+ throw anna::RuntimeException("No entity created", ANNA_FILE_LOCATION);
+ return result;
+}
+
+MyLocalServer *RxSimpleTest::getServer() const throw(anna::RuntimeException) {
+ MyLocalServer *result = (MyLocalServer *)(a_workingNode->getDiameterServer());
+ if (!result)
+ throw anna::RuntimeException("No local server created", ANNA_FILE_LOCATION);
+ return result;
+}
+
+void RxSimpleTest::initialize()
+throw(anna::RuntimeException) {
+ anna::comm::Application::initialize();
+ CommandLine& cl(anna::CommandLine::instantiate());
+ anna::comm::Communicator::WorkMode::_v workMode(anna::comm::Communicator::WorkMode::Single);
+ a_communicator = new MyCommunicator(workMode);
+ a_timeEngine = new anna::timex::Engine((anna::Millisecond)600000, a_admlMinResolution);
+
+ startService();
+}
+
+void RxSimpleTest::run()
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("RxSimpleTest", "run", ANNA_FILE_LOCATION));
+ anna::diameter::stack::Engine::instantiate();
+
+ // Start time:
+ a_start_time.setNow();
+
+ // Initial working directory:
+ char cwd[1024];
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ throw anna::RuntimeException("Cannot retrieve initial working directory !!", ANNA_FILE_LOCATION);
+ a_initialWorkingDirectory = cwd;
+
+ // Statistics:
+ anna::statistics::Engine::instantiate().enable();
+
+ // Start client connections //////////////////////////////////////////////////////////////////////////////////
+ MyDiameterEntity *entity;
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
+ entity = (MyDiameterEntity *)(it->second->getEntity());
+ if (entity) entity->bind();
+ }
+
+ // Go into communicator poll
+ // Reconnection period (tcp reconnect retry time):
+ anna::Millisecond reconnectionPeriod = (anna::Millisecond)10000;
+
+ a_communicator->setRecoveryTime(reconnectionPeriod);
+ a_communicator->accept();
+}
+
+anna::xml::Node* RxSimpleTest::asXML(anna::xml::Node* parent) const
+throw() {
+ anna::xml::Node* result = parent->createChild("rxSimpleTest");
+ anna::comm::Application::asXML(result);
+ // Timming:
+ result->createAttribute("StartTime", a_start_time.asString());
+ result->createAttribute("InitialWorkingDirectory", a_initialWorkingDirectory);
+ result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000);
+ // Diameter:
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
+ it->second->asXML(result);
+ }
+
+ // Registered codec engines:
+ anna::diameter::codec::EngineManager &em = anna::diameter::codec::EngineManager::instantiate();
+ em.asXML(result);
+
+ return result;
+}
+
--- /dev/null
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef example_diameter_rxSimpleTest_hpp
+#define example_diameter_rxSimpleTest_hpp
+
+// Standard
+#include <fstream>
+#include <string>
+#include <map>
+
+// Project
+#include <anna/core/core.hpp>
+#include <anna/comm/comm.hpp>
+#include <anna/time/Date.hpp>
+#include <anna/diameter/codec/Message.hpp>
+
+// Process
+#include <MyCommunicator.hpp>
+
+
+namespace anna {
+ namespace timex {
+ class Engine;
+ }
+ namespace diameter {
+ namespace codec {
+ class Engine;
+ }
+ namespace comm {
+ class OriginHost;
+ }
+ }
+}
+
+class MyDiameterEntity;
+class MyLocalServer;
+class MyDiameterEngine;
+
+class RxSimpleTest : public anna::comm::Application {
+
+ // Start time:
+ anna::time::Date a_start_time;
+
+ // Core engines:
+ MyCommunicator *a_communicator;
+ anna::timex::Engine* a_timeEngine;
+ anna::Millisecond a_admlMinResolution;
+ anna::diameter::comm::OriginHost *a_workingNode;
+ std::string a_initialWorkingDirectory;
+
+
+ void initialize() throw(anna::RuntimeException); // HTTP
+ void run() throw(anna::RuntimeException);
+
+public:
+ RxSimpleTest();
+
+ MyDiameterEntity *getEntity() const throw(anna::RuntimeException);
+ MyLocalServer *getServer() const throw(anna::RuntimeException);
+ MyDiameterEngine *getEngine() const throw(anna::RuntimeException);
+ MyCommunicator *getCommunicator() throw() { return a_communicator; }
+ void startService() throw(anna::RuntimeException);
+ anna::diameter::comm::OriginHost *getOriginHost(const std::string &name) const throw(anna::RuntimeException);
+
+ anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+};
+
+#endif