Yate
yatengine.h
00001 /*
00002  * yatengine.h
00003  * This file is part of the YATE Project http://YATE.null.ro
00004  *
00005  * Engine, plugins and messages related classes
00006  *
00007  * Yet Another Telephony Engine - a fully featured software PBX and IVR
00008  * Copyright (C) 2004-2006 Null Team
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00023  */
00024 
00025 #ifndef __YATENGINE_H
00026 #define __YATENGINE_H
00027 
00028 #ifndef __cplusplus
00029 #error C++ is required
00030 #endif
00031 
00032 #include <yateclass.h>
00033 
00037 namespace TelEngine {
00038 
00043 class YATE_API Configuration : public String
00044 {
00045     YNOCOPY(Configuration); // no automatic copies please
00046 public:
00050     Configuration();
00051 
00057     explicit Configuration(const char* filename, bool warn = true);
00058 
00062     inline Configuration& operator=(const String& value)
00063         { String::operator=(value); return *this; }
00064 
00069     inline unsigned int sections() const
00070         { return m_sections.length(); }
00071 
00077     NamedList* getSection(unsigned int index) const;
00078 
00084     NamedList* getSection(const String& sect) const;
00085 
00092     NamedString* getKey(const String& sect, const String& key) const;
00093 
00101     const char* getValue(const String& sect, const String& key, const char* defvalue = 0) const;
00102 
00114     int getIntValue(const String& sect, const String& key, int defvalue = 0,
00115         int minvalue = INT_MIN, int maxvalue = INT_MAX, bool clamp = true) const;
00116 
00125     int getIntValue(const String& sect, const String& key, const TokenDict* tokens, int defvalue = 0) const;
00126 
00134     double getDoubleValue(const String& sect, const String& key, double defvalue = 0.0) const;
00135 
00143     bool getBoolValue(const String& sect, const String& key, bool defvalue = false) const;
00144 
00149     void clearSection(const char* sect = 0);
00150 
00156     NamedList* createSection(const String& sect);
00157 
00163     void clearKey(const String& sect, const String& key);
00164 
00171     void addValue(const String& sect, const char* key, const char* value = 0);
00172 
00179     void setValue(const String& sect, const char* key, const char* value = 0);
00180 
00187     void setValue(const String& sect, const char* key, int value);
00188 
00195     void setValue(const String& sect, const char* key, bool value);
00196 
00202     bool load(bool warn = true);
00203 
00208     bool save() const;
00209 
00210 private:
00211     ObjList *getSectHolder(const String& sect) const;
00212     ObjList *makeSectHolder(const String& sect);
00213     ObjList m_sections;
00214 };
00215 
00216 class MessageDispatcher;
00217 class MessageRelay;
00218 
00223 class YATE_API Message : public NamedList
00224 {
00225     friend class MessageDispatcher;
00226 public:
00234     explicit Message(const char* name, const char* retval = 0, bool broadcast = false);
00235 
00241     Message(const Message& original);
00242 
00249     Message(const Message& original, bool broadcast);
00250 
00254     ~Message();
00255 
00261     virtual void* getObject(const String& name) const;
00262 
00267     inline String& retValue()
00268         { return m_return; }
00269 
00274     inline const String& retValue() const
00275         { return m_return; }
00276 
00281     inline RefObject* userData() const
00282         { return m_data; }
00283 
00290     void userData(RefObject* data);
00291 
00297     inline void* userObject(const String& name) const
00298         { return m_data ? m_data->getObject(name) : 0; }
00299 
00300 
00306     inline void setNotify(bool notify = true)
00307         { m_notify = notify; }
00308 
00313     inline bool broadcast() const
00314         { return m_broadcast; }
00315 
00320     inline Time& msgTime()
00321         { return m_time; }
00322 
00327     inline const Time& msgTime() const
00328         { return m_time; }
00329 
00333     inline Message& operator=(const char* value)
00334         { String::operator=(value); return *this; }
00335 
00341     String encode(const char* id) const;
00342 
00349     String encode(bool received, const char* id) const;
00350 
00359     int decode(const char* str, String& id);
00360 
00370     int decode(const char* str, bool& received, const char* id);
00371 
00372 protected:
00379     virtual void dispatched(bool accepted);
00380 
00381 private:
00382     Message(); // no default constructor please
00383     Message& operator=(const Message& value); // no assignment please
00384     String m_return;
00385     Time m_time;
00386     RefObject* m_data;
00387     bool m_notify;
00388     bool m_broadcast;
00389     void commonEncode(String& str) const;
00390     int commonDecode(const char* str, int offs);
00391 };
00392 
00399 class YATE_API MessageHandler : public String
00400 {
00401     friend class MessageDispatcher;
00402     friend class MessageRelay;
00403     YNOCOPY(MessageHandler); // no automatic copies please
00404 public:
00410     explicit MessageHandler(const char* name, unsigned priority = 100);
00411 
00415     virtual ~MessageHandler();
00416 
00420     virtual void destruct();
00421 
00427     virtual bool received(Message& msg) = 0;
00428 
00433     inline unsigned priority() const
00434         { return m_priority; }
00435 
00439     inline const NamedString* filter() const
00440         { return m_filter; }
00441 
00447     void setFilter(NamedString* filter);
00448 
00454     inline void setFilter(const char* name, const char* value)
00455         { setFilter(new NamedString(name,value)); }
00456 
00460     void clearFilter();
00461 
00462 protected:
00467     void cleanup();
00468 
00469 private:
00470     virtual bool receivedInternal(Message& msg);
00471     void safeNow();
00472     unsigned m_priority;
00473     int m_unsafe;
00474     MessageDispatcher* m_dispatcher;
00475     NamedString* m_filter;
00476 };
00477 
00482 class YATE_API MessageReceiver : public GenObject
00483 {
00484 public:
00491     virtual bool received(Message& msg, int id) = 0;
00492 };
00493 
00498 class YATE_API MessageRelay : public MessageHandler
00499 {
00500     YNOCOPY(MessageRelay); // no automatic copies please
00501 public:
00509     MessageRelay(const char* name, MessageReceiver* receiver, int id, int priority = 100)
00510         : MessageHandler(name,priority), m_receiver(receiver), m_id(id) { }
00511 
00518     virtual bool received(Message& msg)
00519         { return m_receiver && m_receiver->received(msg,m_id); }
00520 
00525     inline int id() const
00526         { return m_id; }
00527 
00528 private:
00529     virtual bool receivedInternal(Message& msg);
00530     MessageReceiver* m_receiver;
00531     int m_id;
00532 };
00533 
00540 class YATE_API MessageNotifier
00541 {
00542 public:
00546     virtual ~MessageNotifier();
00547 
00553     virtual void dispatched(const Message& msg, bool handled) = 0;
00554 };
00555 
00562 class YATE_API MessagePostHook : public GenObject, public MessageNotifier
00563 {
00564 };
00565 
00572 class YATE_API MessageDispatcher : public GenObject, public Mutex
00573 {
00574     YNOCOPY(MessageDispatcher); // no automatic copies please
00575 public:
00579     MessageDispatcher();
00580 
00584     ~MessageDispatcher();
00585 
00594     bool install(MessageHandler* handler);
00595 
00601     bool uninstall(MessageHandler* handler);
00602 
00614     bool dispatch(Message& msg);
00615 
00621     bool enqueue(Message* msg);
00622 
00626     void dequeue();
00627 
00632     bool dequeueOne();
00633 
00638     inline void warnTime(u_int64_t usec)
00639         { m_warnTime = usec; }
00640 
00644     inline void clear()
00645         { m_handlers.clear(); m_hooks.clear(); }
00646 
00651     unsigned int messageCount();
00652 
00657     unsigned int handlerCount();
00658 
00664     void setHook(MessagePostHook* hook, bool remove = false);
00665 
00666 private:
00667     ObjList m_handlers;
00668     ObjList m_messages;
00669     ObjList m_hooks;
00670     unsigned int m_changes;
00671     u_int64_t m_warnTime;
00672 };
00673 
00684 class YATE_API Plugin : public GenObject, public DebugEnabler
00685 {
00686 public:
00692     explicit Plugin(const char* name, bool earlyInit = false);
00693 
00699     virtual ~Plugin();
00700 
00705     virtual const String& toString() const
00706         { return m_name; }
00707 
00713     virtual void* getObject(const String& name) const;
00714 
00718     virtual void initialize() = 0;
00719 
00724     virtual bool isBusy() const
00725         { return false; }
00726 
00731     inline const String& name() const
00732         { return m_name; }
00733 
00738     bool earlyInit() const
00739         { return m_early; }
00740 
00741 private:
00742     Plugin(); // no default constructor please
00743     String m_name;
00744     bool m_early;
00745 };
00746 
00747 #if 0 /* for documentation generator */
00748 
00752 void INIT_PLUGIN(class pclass);
00753 
00759 bool UNLOAD_PLUGIN(bool unloadNow);
00760 #endif
00761 
00762 #define INIT_PLUGIN(pclass) static pclass __plugin
00763 #ifdef DISABLE_UNLOAD
00764 #define UNLOAD_PLUGIN(arg) static bool _unused_unload(bool arg)
00765 #else
00766 #ifdef _WINDOWS
00767 #define UNLOAD_PLUGIN(arg) extern "C" __declspec(dllexport) bool _unload(bool arg)
00768 #else
00769 #define UNLOAD_PLUGIN(arg) extern "C" bool _unload(bool arg)
00770 #endif
00771 #endif
00772 
00779 class YATE_API EngineCheck
00780 {
00781 public:
00785     virtual ~EngineCheck()
00786         { }
00787 
00794     virtual bool check(const ObjList* cmds) = 0;
00795 
00800     static void setChecker(EngineCheck* ptr = 0);
00801 };
00802 
00806 typedef int (*EngineLoop)();
00807 
00814 class YATE_API Engine
00815 {
00816     friend class EnginePrivate;
00817     friend class EngineCommand;
00818     YNOCOPY(Engine); // no automatic copies please
00819 public:
00823     enum RunMode {
00824         Stopped = 0,
00825         Console = 1,
00826         Server = 2,
00827         Client = 3,
00828         ClientProxy = 4,
00829     };
00830 
00831     enum CallAccept {
00832         Accept = 0,
00833         Partial = 1,
00834         Congestion = 2,
00835         Reject = 3,
00836     };
00837 
00844     enum PluginMode {
00845         LoadFail = 0,
00846         LoadLate,
00847         LoadEarly
00848     };
00849 
00860     static int main(int argc, const char** argv, const char** env,
00861         RunMode mode = Console, EngineLoop loop = 0, bool fail = false);
00862 
00868     static void help(bool client, bool errout = false);
00869 
00874     int engineInit();
00875 
00880     int engineCleanup();
00881 
00886     int run();
00887 
00892     static Engine* self();
00893 
00898     static RunMode mode()
00899         { return s_mode; }
00900 
00905     inline static CallAccept accept() {
00906         return s_accept;
00907     }
00908 
00913     inline static void setAccept(CallAccept ca) {
00914         s_accept = ca;
00915     }
00916 
00921     inline static const TokenDict* getCallAcceptStates() {
00922         return s_callAccept;
00923     }
00924 
00929     inline static bool clientMode()
00930         { return (s_mode == Client) || (s_mode == ClientProxy); }
00931 
00938     static bool Register(const Plugin* plugin, bool reg = true);
00939 
00944     inline static const String& nodeName()
00945         { return s_node; }
00946 
00951     inline static const String& sharedPath()
00952         { return s_shrpath; }
00953 
00960     static String configFile(const char* name, bool user = false);
00961 
00967     static const String& configPath(bool user = false);
00968 
00973     inline static const String& configSuffix()
00974         { return s_cfgsuffix; }
00975 
00979     inline static const String& modulePath()
00980         { return s_modpath; }
00981 
00987     static void extraPath(const String& path);
00988 
00995     static void userPath(const String& path);
00996 
01001     inline static const String& moduleSuffix()
01002         { return s_modsuffix; }
01003 
01008     static const char* pathSeparator();
01009 
01017     static const Configuration& config();
01018 
01023     static unsigned int runId();
01024 
01029     inline static const NamedList& runParams()
01030         { return s_params; }
01031 
01035     static void init();
01036 
01042     static bool init(const String& name);
01043 
01048     static void halt(unsigned int code);
01049 
01056     static bool restart(unsigned int code, bool gracefull = false);
01057 
01062     static bool exiting()
01063         { return (s_haltcode != -1); }
01064 
01070     static bool install(MessageHandler* handler);
01071 
01077     static bool uninstall(MessageHandler* handler);
01078 
01084     static bool enqueue(Message* msg);
01085 
01093     inline static bool enqueue(const char* name, bool broadcast = false)
01094         { return name && *name && enqueue(new Message(name,0,broadcast)); }
01095 
01101     static bool dispatch(Message* msg);
01102 
01108     static bool dispatch(Message& msg);
01109 
01117     static bool dispatch(const char* name, bool broadcast = false);
01118 
01124     inline void setHook(MessagePostHook* hook, bool remove = false)
01125         { m_dispatcher.setHook(hook,remove); }
01126 
01131     int usedPlugins();
01132 
01137     inline unsigned int messageCount()
01138         { return m_dispatcher.messageCount(); }
01139 
01144     inline unsigned int handlerCount()
01145         { return m_dispatcher.handlerCount(); }
01146 
01152     bool loadPluginDir(const String& relPath);
01153 
01158     static void pluginMode(PluginMode mode);
01159 
01165     static const ObjList* events(const String& type);
01166 
01171     static void clearEvents(const String& type);
01172 
01173 protected:
01178     ~Engine();
01179 
01187     bool loadPlugin(const char* file, bool local = false, bool nounload = false);
01188 
01192     void loadPlugins();
01193 
01197     void initPlugins();
01198 
01199 private:
01200     Engine();
01201     void internalStatisticsStart();
01202     ObjList m_libs;
01203     MessageDispatcher m_dispatcher;
01204     static Engine* s_self;
01205     static String s_node;
01206     static String s_shrpath;
01207     static String s_cfgsuffix;
01208     static String s_modpath;
01209     static String s_modsuffix;
01210     static ObjList s_extramod;
01211     static NamedList s_params;
01212     static int s_haltcode;
01213     static RunMode s_mode;
01214     static CallAccept s_accept;
01215     static const TokenDict s_callAccept[];
01216 };
01217 
01218 }; // namespace TelEngine
01219 
01220 #endif /* __YATENGINE_H */
01221 
01222 /* vi: set ts=8 sw=4 sts=4 noet: */