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 public:
00049     Configuration();
00050 
00056     Configuration(const char* filename, bool warn = true);
00057 
00061     inline Configuration& operator=(const String& value)
00062         { String::operator=(value); return *this; }
00063 
00068     inline unsigned int sections() const
00069         { return m_sections.length(); }
00070 
00076     NamedList* getSection(unsigned int index) const;
00077 
00083     NamedList* getSection(const String& sect) const;
00084 
00091     NamedString* getKey(const String& sect, const String& key) const;
00092 
00100     const char* getValue(const String& sect, const String& key, const char* defvalue = 0) const;
00101 
00109     int getIntValue(const String& sect, const String& key, int defvalue = 0) const;
00110 
00119     int getIntValue(const String& sect, const String& key, const TokenDict* tokens, int defvalue = 0) const;
00120 
00128     double getDoubleValue(const String& sect, const String& key, double defvalue = 0.0) const;
00129 
00137     bool getBoolValue(const String& sect, const String& key, bool defvalue = false) const;
00138 
00143     void clearSection(const char* sect = 0);
00144 
00149     inline void createSection(const String& sect)
00150         { if (sect) makeSectHolder(sect); }
00151 
00157     void clearKey(const String& sect, const String& key);
00158 
00165     void addValue(const String& sect, const char* key, const char* value = 0);
00166 
00173     void setValue(const String& sect, const char* key, const char* value = 0);
00174 
00181     void setValue(const String& sect, const char* key, int value);
00182 
00189     void setValue(const String& sect, const char* key, bool value);
00190 
00196     bool load(bool warn = true);
00197 
00202     bool save() const;
00203 
00204 private:
00205     Configuration(const Configuration& value); // no copy constructor
00206     Configuration& operator=(const Configuration& value); // no assignment please
00207     ObjList *getSectHolder(const String& sect) const;
00208     ObjList *makeSectHolder(const String& sect);
00209     ObjList m_sections;
00210 };
00211 
00212 class MessageDispatcher;
00213 class MessageRelay;
00214 
00219 class YATE_API Message : public NamedList
00220 {
00221     friend class MessageDispatcher;
00222 public:
00229     Message(const char* name, const char* retval = 0);
00230 
00236     Message(const Message& original);
00237 
00241     ~Message();
00242 
00248     virtual void* getObject(const String& name) const;
00249 
00254     inline String& retValue()
00255         { return m_return; }
00256 
00261     inline const String& retValue() const
00262         { return m_return; }
00263 
00268     inline RefObject* userData() const
00269         { return m_data; }
00270 
00277     void userData(RefObject* data);
00278 
00284     inline void* userObject(const String& name) const
00285         { return m_data ? m_data->getObject(name) : 0; }
00286 
00287 
00293     inline void setNotify(bool notify = true)
00294         { m_notify = notify; }
00295 
00300     inline Time& msgTime()
00301         { return m_time; }
00302 
00307     inline const Time& msgTime() const
00308         { return m_time; }
00309 
00313     inline Message& operator=(const char* value)
00314         { String::operator=(value); return *this; }
00315 
00321     String encode(const char* id) const;
00322 
00329     String encode(bool received, const char* id) const;
00330 
00339     int decode(const char* str, String& id);
00340 
00350     int decode(const char* str, bool& received, const char* id);
00351 
00352 protected:
00359     virtual void dispatched(bool accepted);
00360 
00361 private:
00362     Message(); // no default constructor please
00363     Message& operator=(const Message& value); // no assignment please
00364     String m_return;
00365     Time m_time;
00366     RefObject* m_data;
00367     bool m_notify;
00368     void commonEncode(String& str) const;
00369     int commonDecode(const char* str, int offs);
00370 };
00371 
00378 class YATE_API MessageHandler : public String
00379 {
00380     friend class MessageDispatcher;
00381     friend class MessageRelay;
00382 public:
00388     MessageHandler(const char* name, unsigned priority = 100);
00389 
00393     virtual ~MessageHandler();
00394 
00398     virtual void destruct();
00399 
00405     virtual bool received(Message& msg) = 0;
00406 
00411     inline unsigned priority() const
00412         { return m_priority; }
00413 
00417     inline const NamedString* filter() const
00418         { return m_filter; }
00419 
00425     void setFilter(NamedString* filter);
00426 
00432     inline void setFilter(const char* name, const char* value)
00433         { setFilter(new NamedString(name,value)); }
00434 
00438     void clearFilter();
00439 
00440 protected:    
00445     void cleanup();
00446 
00447 private:
00448     virtual bool receivedInternal(Message& msg);
00449     void safeNow();
00450     unsigned m_priority;
00451     int m_unsafe;
00452     MessageDispatcher* m_dispatcher;
00453     NamedString* m_filter;
00454 };
00455 
00460 class YATE_API MessageReceiver : public GenObject
00461 {
00462 public:
00469     virtual bool received(Message& msg, int id) = 0;
00470 };
00471 
00476 class YATE_API MessageRelay : public MessageHandler
00477 {
00478 public:
00486     MessageRelay(const char* name, MessageReceiver* receiver, int id, int priority = 100)
00487         : MessageHandler(name,priority), m_receiver(receiver), m_id(id) { }
00488 
00495     virtual bool received(Message& msg)
00496         { return m_receiver && m_receiver->received(msg,m_id); }
00497 
00502     inline int id() const
00503         { return m_id; }
00504 
00505 private:
00506     virtual bool receivedInternal(Message& msg);
00507     MessageReceiver* m_receiver;
00508     int m_id;
00509 };
00510 
00517 class YATE_API MessageNotifier
00518 {
00519 public:
00523     virtual ~MessageNotifier();
00524 
00530     virtual void dispatched(const Message& msg, bool handled) = 0;
00531 };
00532 
00539 class YATE_API MessagePostHook : public GenObject, public MessageNotifier
00540 {
00541 };
00542 
00549 class YATE_API MessageDispatcher : public GenObject, public Mutex
00550 {
00551 public:
00555     MessageDispatcher();
00556 
00560     ~MessageDispatcher();
00561 
00570     bool install(MessageHandler* handler);
00571 
00577     bool uninstall(MessageHandler* handler);
00578 
00588     bool dispatch(Message& msg);
00589 
00595     bool enqueue(Message* msg);
00596 
00600     void dequeue();
00601 
00606     bool dequeueOne();
00607 
00612     inline void warnTime(u_int64_t usec)
00613         { m_warnTime = usec; }
00614 
00618     inline void clear()
00619         { m_handlers.clear(); m_hooks.clear(); }
00620 
00625     unsigned int messageCount();
00626 
00631     unsigned int handlerCount();
00632 
00638     void setHook(MessagePostHook* hook, bool remove = false);
00639 
00640 private:
00641     ObjList m_handlers;
00642     ObjList m_messages;
00643     ObjList m_hooks;
00644     unsigned int m_changes;
00645     u_int64_t m_warnTime;
00646 };
00647 
00658 class YATE_API Plugin : public GenObject
00659 {
00660 public:
00666     Plugin(const char* name, bool earlyInit = false);
00667 
00672     Plugin();
00673 
00679     virtual ~Plugin();
00680 
00686     virtual void* getObject(const String& name) const;
00687 
00691     virtual void initialize() = 0;
00692 
00697     virtual bool isBusy() const
00698         { return false; }
00699 
00704     bool earlyInit() const
00705         { return m_early; }
00706 
00707 private:
00708     bool m_early;
00709 };
00710 
00711 #if 0 /* for documentation generator */
00712 
00716 void INIT_PLUGIN(class pclass);
00717 
00723 bool UNLOAD_PLUGIN(bool unloadNow);
00724 #endif
00725 
00726 #define INIT_PLUGIN(pclass) static pclass __plugin
00727 #ifdef DISABLE_UNLOAD
00728 #define UNLOAD_PLUGIN(arg) static bool _unused_unload(bool arg)
00729 #else
00730 #ifdef _WINDOWS
00731 #define UNLOAD_PLUGIN(arg) extern "C" __declspec(dllexport) bool _unload(bool arg)
00732 #else
00733 #define UNLOAD_PLUGIN(arg) extern "C" bool _unload(bool arg)
00734 #endif
00735 #endif
00736 
00743 class YATE_API EngineCheck
00744 {
00745 public:
00749     virtual ~EngineCheck()
00750         { }
00751 
00758     virtual bool check(const ObjList* cmds) = 0;
00759 
00764     static void setChecker(EngineCheck* ptr = 0);
00765 };
00766 
00773 class YATE_API Engine
00774 {
00775     friend class EnginePrivate;
00776     friend class EngineCommand;
00777 public:
00781     enum RunMode {
00782         Stopped = 0,
00783         Console = 1,
00784         Server = 2,
00785         Client = 3,
00786         ClientProxy = 4,
00787     };
00788 
00795     enum PluginMode {
00796         LoadFail = 0,
00797         LoadLate,
00798         LoadEarly
00799     };
00800 
00810     static int main(int argc, const char** argv, const char** env,
00811         RunMode mode = Console, bool fail = false);
00812 
00818     static void help(bool client, bool errout = false);
00819 
00824     int run();
00825 
00830     static Engine* self();
00831 
00836     static RunMode mode()
00837         { return s_mode; }
00838 
00843     inline static bool clientMode()
00844         { return (s_mode == Client) || (s_mode == ClientProxy); }
00845 
00852     static bool Register(const Plugin* plugin, bool reg = true);
00853 
00858     inline static const String& nodeName()
00859         { return s_node; }
00860 
00865     inline static const String& sharedPath()
00866         { return s_shrpath; }
00867 
00874     static String configFile(const char* name, bool user = false);
00875 
00881     static const String& configPath(bool user = false);
00882 
00887     inline static const String& configSuffix()
00888         { return s_cfgsuffix; }
00889 
00893     inline static const String& modulePath()
00894         { return s_modpath; }
00895 
00901     static void extraPath(const String& path);
00902 
00909     static void userPath(const String& path);
00910 
00915     inline static const String& moduleSuffix()
00916         { return s_modsuffix; }
00917 
00922     static const char* pathSeparator();
00923 
00931     static const Configuration& config();
00932 
00937     static unsigned int runId();
00938 
00943     inline static const NamedList& runParams()
00944         { return s_params; }
00945 
00949     static void init();
00950 
00955     static void halt(unsigned int code);
00956 
00963     static bool restart(unsigned int code, bool gracefull = false);
00964 
00969     static bool exiting()
00970         { return (s_haltcode != -1); }
00971 
00977     static bool install(MessageHandler* handler);
00978 
00984     static bool uninstall(MessageHandler* handler);
00985 
00991     static bool enqueue(Message* msg);
00992 
00999     inline static bool enqueue(const char* name)
01000         { return (name && *name) ? enqueue(new Message(name)) : false; }
01001 
01007     static bool dispatch(Message* msg);
01008 
01014     static bool dispatch(Message& msg);
01015 
01022     static bool dispatch(const char* name);
01023 
01029     inline void setHook(MessagePostHook* hook, bool remove = false)
01030         { m_dispatcher.setHook(hook,remove); }
01031 
01036     int usedPlugins();
01037 
01042     inline unsigned int messageCount()
01043         { return m_dispatcher.messageCount(); }
01044 
01049     inline unsigned int handlerCount()
01050         { return m_dispatcher.handlerCount(); }
01051 
01057     bool loadPluginDir(const String& relPath);
01058 
01063     static void pluginMode(PluginMode mode);
01064 
01065 protected:
01070     ~Engine();
01071 
01079     bool loadPlugin(const char* file, bool local = false, bool nounload = false);
01080 
01084     void loadPlugins();
01085 
01089     void initPlugins();
01090 
01091 private:
01092     Engine();
01093     ObjList m_libs;
01094     MessageDispatcher m_dispatcher;
01095     static Engine* s_self;
01096     static String s_node;
01097     static String s_shrpath;
01098     static String s_cfgsuffix;
01099     static String s_modpath;
01100     static String s_modsuffix;
01101     static ObjList s_extramod;
01102     static NamedList s_params;
01103     static int s_haltcode;
01104     static RunMode s_mode;
01105 };
01106 
01107 }; // namespace TelEngine
01108 
01109 #endif /* __YATENGINE_H */
01110 
01111 /* vi: set ts=8 sw=4 sts=4 noet: */