⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nasd_call_framework.h

📁 在Diameter3588协议的基础上开发的软件
💻 H
字号:
/* BEGIN_COPYRIGHT                                                        *//*                                                                        *//* Open Diameter: Open-source software for the Diameter and               *//*                Diameter related protocols                              *//*                                                                        *//* Copyright (C) 2002-2007 Open Diameter Project                          *//*                                                                        *//* This library 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 library 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 library; if not, write to the Free Software    *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307    *//* USA.                                                                   *//*                                                                        *//* In addition, when you copy and redistribute some or the entire part of *//* the source code of this software with or without modification, you     *//* MUST include this copyright notice in each copy.                       *//*                                                                        *//* If you make any changes that are appeared to be useful, please send    *//* sources that include the changed part to                               *//* diameter-developers@lists.sourceforge.net so that we can reflect your  *//* changes to one unified version of this software.                       *//*                                                                        *//* END_COPYRIGHT                                                          */#ifndef __NASD_CALL_FRAMEWORK_H__#define __NASD_CALL_FRAMEWORK_H__#include <map>#include <string>#include <ace/Singleton.h>#include "framework.h"#include "diameter_parser.h"#include "nasd_config.h"class NASD_CallElement :   public AAA_JobData{   public:      virtual ~NASD_CallElement() {      }      virtual int Start() = 0;      virtual bool IsRunning() = 0;      virtual void Stop() = 0;     };class NASD_CallElementFactoryCreateCallback{   public:      virtual NASD_CallElement *Create(AAA_Task &t) = 0;      virtual ~NASD_CallElementFactoryCreateCallback() { }};class NASD_CallElementFactory{   public:      typedef std::map<std::string,                        NASD_CallElementFactoryCreateCallback*>                        CallbackMap;         public:      NASD_CallElementFactory(AAA_Task &t) :           m_Task(t) {      }      bool Register(std::string &name,                     NASD_CallElementFactoryCreateCallback &cb) {          return m_Map.insert(CallbackMap::value_type(name, &cb)).second;      }      bool UnRegister(std::string &id) {          return (m_Map.erase(id) == 1);      }      NASD_CallElement *Create(std::string &name) {          CallbackMap::iterator i = m_Map.find(name);          if (i != m_Map.end()) {                            return (*(i->second)).Create(m_Task);          }          return 0;      }            NASD_CallElementFactoryCreateCallback* Lookup(std::string &name) {          CallbackMap::iterator i = m_Map.find(name);          return (i != m_Map.end()) ? i->second : 0;      }         protected:      AAA_Task &m_Task;      CallbackMap m_Map;};class NASD_CallNode;typedef NASD_CallNode* NASD_CnPtr;////// Basic definition of a NASD node/// Notes:///    Implementors MUST inherit this class///    and implement ReceiveIngress() and///    ReceiveEgress() methods///class NASD_CallNode :    public NASD_CallElement{   public:      NASD_CallNode() :         m_Prev(NULL),         m_Next(NULL) {      }      NASD_CallNode(NASD_CnPtr prev,                    NASD_CnPtr next) :          m_Prev(prev),          m_Next(next) {      }      virtual NASD_CnPtr &NextNode() {          return m_Next;      }      virtual NASD_CnPtr &PrevNode() {          return m_Prev;      }      virtual int SendIngress(AAAMessageBlock &msg) {          return (m_Next) ? m_Next->ReceiveIngress(msg) : -1;      }      virtual int SendEgress(AAAMessageBlock &msg) {          return (m_Prev) ? m_Prev->ReceiveEgress(msg) : -1;      }      virtual bool CurrentKey(std::string &key) = 0;      virtual bool Identity(std::string &ident) = 0;      virtual int ReceiveIngress(AAAMessageBlock &msg) = 0;      virtual int ReceiveEgress(AAAMessageBlock &msg) = 0;      virtual void Success(AAAMessageBlock *msg = 0) = 0;      virtual void Failure(AAAMessageBlock *msg = 0) = 0;      virtual void Timeout() = 0;      virtual void Error() = 0;         protected:      NASD_CnPtr m_Prev;      NASD_CnPtr m_Next;};class NASD_CnGarbageCollector :  public AAA_Job{    public:        NASD_CnGarbageCollector(AAA_Task &t) :            m_GroupedJob(AAA_GroupedJob::Create(t.Job(),	                 (AAA_JobData*)this)),             m_Enabled(true) {	}        virtual ~NASD_CnGarbageCollector() {            m_Enabled = false;            while (! m_DeleteQueue.empty()) {               ACE_Time_Value tv(0, 100000);               ACE_OS::sleep(tv);	    }	}        void ScheduleForDeletion(NASD_CallNode &ch) {            if (m_Enabled) {               AAA_ScopeLock<ACE_Mutex> guard(m_Lock);               m_DeleteQueue.push_back(&ch);               Schedule(this);	    }            	}    protected:        int Schedule(AAA_Job *job, size_t backlogSize=1) {            return m_GroupedJob->Schedule(job, backlogSize);        }        int Serve() {            NASD_CnPtr node = NULL;            try {                AAA_ScopeLock<ACE_Mutex> guard(m_Lock);                if (m_DeleteQueue.size() == 0) {                    NASD_LOG(LM_INFO,                         "(%P|%t) WARNING: Garbage collector schedule with empty queue\n");                    return (0);		}                node = m_DeleteQueue.front();                if (! node->IsRunning()) {                    m_DeleteQueue.pop_front();                }                else {		    node->Stop();	            Schedule(this);                    NASD_LOG(LM_INFO,                         "(%P|%t) *** Re-scheduling collection ***\n");                    return (0);	        }	    }            catch (...) {	    }            if (node) {                NASD_LOG(LM_INFO,                     "(%P|%t) *** Garbage collection occuring ***\n");                /// TBD: Fix this !!!                ACE_Time_Value tm(3, 0);		ACE_OS::sleep(tm);                delete node;	    }            return (0);           	}    private:        ACE_Mutex m_Lock;        AAA_JobHandle<AAA_GroupedJob> m_GroupedJob;               std::list<NASD_CnPtr> m_DeleteQueue;        bool m_Enabled;};class NASD_CnGarbageCollectorSingleton{    public:        virtual ~NASD_CnGarbageCollectorSingleton() {	}        void Initialize(AAA_Task &t) {            m_Instance = std::auto_ptr<NASD_CnGarbageCollector> 		    (new NASD_CnGarbageCollector(t));	}        NASD_CnGarbageCollector &Instance() {            // this will throw when used improperly            return (*m_Instance);	}    private:        std::auto_ptr< NASD_CnGarbageCollector >               m_Instance;};typedef ACE_Singleton<NASD_CnGarbageCollectorSingleton, ACE_Null_Mutex>         NASD_CnGarbageCollector_S;#define NASD_CnGarbageCollector_I NASD_CnGarbageCollector_S::instance()#define NASD_GARBAGE_COLLECTOR() NASD_CnGarbageCollector_I->Instance()class NASD_CnAccessPolicy :   public NASD_CallElement{   public:      NASD_CnAccessPolicy(AAA_Task &t) {      }      virtual bool Execute() = 0;};class NASD_CnAaaProtocol :   public NASD_CallNode{   public:      NASD_CnAaaProtocol(AAA_Task &t) {      }};class NASD_CnInitCallback :    public NASD_CallElementFactoryCreateCallback{    public:        virtual bool Initialize(AAA_Task &t) {           return true;        }        virtual bool UnInitialize()  {           return true;        }        virtual NASD_CallElement *Create(AAA_Task &t) {           return NULL;	}    protected:        NASD_CnInitCallback() {	}        virtual ~NASD_CnInitCallback() {	}};class NASD_CnInitializer :     public NASD_CallElementFactory{    public:        NASD_CnInitializer() :           NASD_CallElementFactory(m_Task) {        }        AAA_Task &Task() {           return m_Task;	}        bool IsRunning() {           return m_Task.Running();	}        bool Start(const char *cfgfile = 0) {           /// Garbage collection           NASD_CnGarbageCollector_I->Initialize(m_Task);                      /// Configuration parsing           NASD_CfgLoader cfgLoader(cfgfile);           NASD_CALLMNGT_DATA()->Dump();           /// AAA_Task           m_Task.Start(NASD_CALLMNGT_DATA()->ThreadCount());           /// Initialize all registered members	   NASD_CallElementFactory::CallbackMap::iterator i;           for (i = m_Map.begin(); i != m_Map.end(); i++) {                NASD_CnInitCallback *cb = (NASD_CnInitCallback*)i->second;                cb->Initialize(m_Task);	   }                      return true;	}        void Stop() {           /// Un-initialize all registered members	   NASD_CallElementFactory::CallbackMap::iterator i;           for (i = m_Map.begin(); i != m_Map.end(); i++) {                NASD_CnInitCallback *cb = (NASD_CnInitCallback*)i->second;                cb->UnInitialize();	   }                      m_Task.Stop();	}    private:        AAA_Task m_Task;};typedef ACE_Singleton<NASD_CnInitializer, ACE_Null_Mutex>         NASD_CnInitializer_S;#define NASD_CnInitializer_I NASD_CnInitializer_S::instance() class NASD_CallRouting :   public NASD_CallNode{   public:      virtual bool IncommingCall(std::string &nai) {         // Lookup the route         NASD_RouteEntry *rte = (NASD_RouteEntry*)NASD_CALLROUTE_TBL().                                      Lookup(nai);         if (rte == NULL) {             NASD_LOG(LM_INFO, "(%P|%t) Route failure for [%s]\n",                       nai.data());             return false;	 }         NASD_LOG(LM_INFO, "(%P|%t) Routing call for [%s] using [%s]\n",                   nai.data(), rte->Nai().data());         // Execute all access policies	 NASD_RouteEntry::AccessPolicyList::iterator i;         for (i = rte->PolicyList().begin();               i != rte->PolicyList().end();              i ++) {             NASD_CnAccessPolicy *CnAp = (NASD_CnAccessPolicy*)                    NASD_CnInitializer_I->Create(*i);             if (CnAp) {                 if (! CnAp->Execute()) {                     NASD_LOG(LM_INFO, "(%P|%t) Failed on access policy [%s]\n",                               (*i).data());                     return false;                 }	     }             else {                 NASD_LOG(LM_INFO, "(%P|%t) Policy [%s] is not registered\n",                           (*i).data());	     }	 }         // Create AAA protocols         NASD_CnPtr CnAaa = (NASD_CnAaaProtocol*)             NASD_CnInitializer_I->Create(rte->AaaProtocol());         if (CnAaa == NULL) {             NASD_LOG(LM_INFO, "(%P|%t) Failed to create %s for %s\n",                       rte->AaaProtocol().data(), nai.data());             return false;	 }         NASD_LOG(LM_INFO, "(%P|%t) Call routed to [%s]\n",                   rte->AaaProtocol().data());         // Bind passthrough with aaa         NextNode() = CnAaa;         CnAaa->PrevNode() = this;         // Start the AAA protocol         CnAaa->Start();         return true;      }   protected:      virtual ~NASD_CallRouting() {      }};template <class LOCAL_PASSTHROUGH>class NASD_CnAccessProtocol :   public NASD_CallNode{   public:      NASD_CnAccessProtocol(AAA_Task &t) :         m_LocalPassThrough(t) {         NextNode() = &m_LocalPassThrough;         m_LocalPassThrough.PrevNode() = this;      }          virtual ~NASD_CnAccessProtocol() {	 NASD_CnPtr cnPtr = m_LocalPassThrough.NextNode();         while (cnPtr) {	    NASD_GARBAGE_COLLECTOR().                ScheduleForDeletion(*cnPtr);            cnPtr = cnPtr->NextNode();	 }      }          LOCAL_PASSTHROUGH &PassThrough() {         return m_LocalPassThrough;      }   protected:      LOCAL_PASSTHROUGH m_LocalPassThrough;};#endif // __NASD_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -