00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __YATEPHONE_H
00026 #define __YATEPHONE_H
00027
00028 #ifndef __cplusplus
00029 #error C++ is required
00030 #endif
00031
00032 #include <yatengine.h>
00033
00037 namespace TelEngine {
00038
00042 struct YATE_API ImageInfo {
00046 int width;
00047
00051 int height;
00052
00056 int depth;
00057 };
00058
00062 struct YATE_API FormatInfo {
00066 const char* name;
00067
00071 const char* type;
00072
00076 int frameSize;
00077
00081 int frameTime;
00082
00086 int sampleRate;
00087
00091 int numChannels;
00092
00096 bool converter;
00097
00103 int guessSamples(int len) const;
00104
00109 int dataRate() const;
00110
00114 inline FormatInfo()
00115 : name(0), type("audio"),
00116 frameSize(0), frameTime(0),
00117 sampleRate(8000), numChannels(1),
00118 converter(false)
00119 { }
00120
00124 inline FormatInfo(const char* _name, int fsize = 0, int ftime = 10000,
00125 const char* _type = "audio", int srate = 8000, int nchan = 1, bool convert = false)
00126 : name(_name), type(_type),
00127 frameSize(fsize), frameTime(ftime),
00128 sampleRate(srate), numChannels(nchan),
00129 converter(convert)
00130 { }
00131 };
00132
00133 class CallEndpoint;
00134 class Driver;
00135
00140 struct YATE_API TranslatorCaps {
00142 const FormatInfo* src;
00144 const FormatInfo* dest;
00146 int cost;
00147 };
00148
00153 class YATE_API FormatRepository
00154 {
00155 private:
00156 FormatRepository();
00157 FormatRepository& operator=(const FormatRepository&);
00158 public:
00164 static const FormatInfo* getFormat(const String& name);
00165
00177 static const FormatInfo* addFormat(const String& name, int fsize, int ftime, const String& type = "audio", int srate = 8000, int nchan = 1);
00178 };
00179
00184 class YATE_API DataFormat : public String
00185 {
00186 public:
00190 inline DataFormat()
00191 : m_parsed(0)
00192 { }
00193
00198 inline DataFormat(const char* value)
00199 : String(value), m_parsed(0)
00200 { }
00201
00206 inline DataFormat(const DataFormat& value)
00207 : String(value), m_parsed(value.getInfo())
00208 { }
00209
00214 inline DataFormat(const String& value)
00215 : String(value), m_parsed(0)
00216 { }
00217
00222 inline DataFormat(const String* value)
00223 : String(value), m_parsed(0)
00224 { }
00225
00230 inline DataFormat(const FormatInfo* format)
00231 : String(format ? format->name : (const char*)0), m_parsed(format)
00232 { }
00233
00237 inline DataFormat& operator=(const DataFormat& value)
00238 { String::operator=(value); return *this; }
00239
00244 const FormatInfo* getInfo() const;
00245
00251 inline int frameSize(int defValue = 0) const
00252 { return getInfo() ? getInfo()->frameSize : defValue; }
00253
00259 inline int frameTime(int defValue = 0) const
00260 { return getInfo() ? getInfo()->frameTime : defValue; }
00261
00268 inline int sampleRate(int defValue = 0) const
00269 { return getInfo() ? getInfo()->sampleRate : defValue; }
00270
00276 inline int numChannels(int defValue = 1) const
00277 { return getInfo() ? getInfo()->numChannels : defValue; }
00278
00279 protected:
00283 virtual void changed();
00284
00285 private:
00286 mutable const FormatInfo* m_parsed;
00287 };
00288
00292 class YATE_API DataNode : public RefObject
00293 {
00294 public:
00299 inline DataNode(const char* format = 0)
00300 : m_format(format), m_timestamp(0)
00301 { }
00302
00308 virtual int costFormat(const DataFormat& format)
00309 { return -1; }
00310
00316 virtual bool setFormat(const DataFormat& format)
00317 { return false; }
00318
00323 inline const DataFormat& getFormat() const
00324 { return m_format; }
00325
00330 inline unsigned long timeStamp() const
00331 { return m_timestamp; }
00332
00337 inline static unsigned long invalidStamp()
00338 { return (unsigned long)-1; }
00339
00340 protected:
00341 DataFormat m_format;
00342 unsigned long m_timestamp;
00343 };
00344
00345 class DataSource;
00346 class DataTranslator;
00347 class TranslatorFactory;
00348 class ThreadedSourcePrivate;
00349
00353 class YATE_API DataConsumer : public DataNode
00354 {
00355 friend class DataSource;
00356
00357 public:
00362 inline DataConsumer(const char* format = "slin")
00363 : DataNode(format),
00364 m_source(0), m_override(0),
00365 m_regularTsDelta(0), m_overrideTsDelta(0), m_lastTsTime(0)
00366 { }
00367
00371 virtual void destroyed();
00372
00378 virtual void* getObject(const String& name) const;
00379
00385 virtual void Consume(const DataBlock& data, unsigned long tStamp) = 0;
00386
00391 inline DataSource* getConnSource() const
00392 { return m_source; }
00393
00398 inline DataSource* getOverSource() const
00399 { return m_override; }
00400
00405 virtual DataSource* getTransSource() const
00406 { return 0; }
00407
00408 protected:
00414 virtual bool synchronize(DataSource* source);
00415
00416 private:
00417 void Consume(const DataBlock& data, unsigned long tStamp, DataSource* source);
00418 DataSource* m_source;
00419 DataSource* m_override;
00420 long m_regularTsDelta;
00421 long m_overrideTsDelta;
00422 u_int64_t m_lastTsTime;
00423 };
00424
00428 class YATE_API DataSource : public DataNode
00429 {
00430 friend class DataTranslator;
00431
00432 public:
00437 inline DataSource(const char* format = "slin")
00438 : DataNode(format), m_nextStamp(invalidStamp()), m_translator(0) { }
00439
00443 virtual void destroyed();
00444
00450 virtual void* getObject(const String& name) const;
00451
00457 void Forward(const DataBlock& data, unsigned long tStamp = invalidStamp());
00458
00465 bool attach(DataConsumer* consumer, bool override = false);
00466
00472 bool detach(DataConsumer* consumer);
00473
00477 void clear();
00478
00483 inline Mutex* mutex()
00484 { return &m_mutex; }
00485
00490 inline DataTranslator* getTranslator() const
00491 { return m_translator; }
00492
00497 void synchronize(unsigned long tStamp);
00498
00503 inline unsigned long nextStamp() const
00504 { return m_nextStamp; }
00505
00506 protected:
00507 unsigned long m_nextStamp;
00508 DataTranslator* m_translator;
00509 ObjList m_consumers;
00510 Mutex m_mutex;
00511 private:
00512 inline void setTranslator(DataTranslator* translator)
00513 { m_translator = translator; }
00514 bool detachInternal(DataConsumer* consumer);
00515 };
00516
00520 class YATE_API ThreadedSource : public DataSource
00521 {
00522 friend class ThreadedSourcePrivate;
00523 public:
00527 virtual void destroyed();
00528
00535 bool start(const char* name = "ThreadedSource", Thread::Priority prio = Thread::Normal);
00536
00540 void stop();
00541
00546 Thread* thread() const;
00547
00552 bool running() const;
00553
00557 inline bool asyncDelete() const
00558 { return m_asyncDelete; }
00559
00560 protected:
00565 inline ThreadedSource(const char* format = "slin")
00566 : DataSource(format), m_thread(0), m_asyncDelete(false)
00567 { }
00568
00573 inline void asyncDelete(bool async)
00574 { m_asyncDelete = async; }
00575
00579 inline void clearThread()
00580 { m_thread = 0; }
00581
00585 virtual void run() = 0;
00586
00591 virtual void cleanup();
00592
00598 virtual bool zeroRefsTest();
00599
00600 private:
00601 ThreadedSourcePrivate* m_thread;
00602 bool m_asyncDelete;
00603 };
00604
00610 class YATE_API DataTranslator : public DataConsumer
00611 {
00612 friend class TranslatorFactory;
00613 public:
00619 DataTranslator(const char* sFormat, const char* dFormat);
00620
00627 DataTranslator(const char* sFormat, DataSource* source = 0);
00628
00632 ~DataTranslator();
00633
00639 virtual void* getObject(const String& name) const;
00640
00645 virtual DataSource* getTransSource() const
00646 { return m_tsource; }
00647
00652 DataTranslator* getFirstTranslator();
00653
00658 const DataTranslator* getFirstTranslator() const;
00659
00668 static ObjList* srcFormats(const DataFormat& dFormat = "slin", int maxCost = -1, unsigned int maxLen = 0, ObjList* lst = 0);
00669
00678 static ObjList* destFormats(const DataFormat& sFormat = "slin", int maxCost = -1, unsigned int maxLen = 0, ObjList* lst = 0);
00679
00688 static ObjList* allFormats(const ObjList* formats, bool existing = true, bool sameRate = true, bool sameChans = true);
00689
00698 static ObjList* allFormats(const String& formats, bool existing = true, bool sameRate = true, bool sameChans = true);
00699
00706 static bool canConvert(const DataFormat& fmt1, const DataFormat& fmt2 = "slin");
00707
00714 static int cost(const DataFormat& sFormat, const DataFormat& dFormat);
00715
00722 static DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat);
00723
00731 static bool attachChain(DataSource* source, DataConsumer* consumer, bool override = false);
00732
00739 static bool detachChain(DataSource* source, DataConsumer* consumer);
00740
00745 static void setMaxChain(unsigned int maxChain);
00746
00747 protected:
00753 virtual bool synchronize(DataSource* source);
00754
00759 static void install(TranslatorFactory* factory);
00760
00765 static void uninstall(TranslatorFactory* factory);
00766
00767 private:
00768 DataTranslator();
00769 static void compose();
00770 static void compose(TranslatorFactory* factory);
00771 static bool canConvert(const FormatInfo* fmt1, const FormatInfo* fmt2);
00772 DataSource* m_tsource;
00773 static Mutex s_mutex;
00774 static ObjList s_factories;
00775 static unsigned int s_maxChain;
00776 };
00777
00783 class YATE_API TranslatorFactory : public GenObject
00784 {
00785 protected:
00789 inline TranslatorFactory()
00790 { DataTranslator::install(this); }
00791
00792 public:
00796 virtual ~TranslatorFactory();
00797
00802 virtual void removed(const TranslatorFactory* factory);
00803
00810 virtual DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat) = 0;
00811
00816 virtual const TranslatorCaps* getCapabilities() const = 0;
00817
00824 virtual bool converts(const DataFormat& sFormat, const DataFormat& dFormat) const;
00825
00830 virtual unsigned int length() const;
00831
00837 virtual bool intermediate(const FormatInfo* info) const;
00838
00843 virtual const FormatInfo* intermediate() const;
00844 };
00845
00851 class YATE_API DataEndpoint : public RefObject
00852 {
00853 public:
00854
00858 DataEndpoint(CallEndpoint* call = 0, const char* name = "audio");
00859
00863 virtual void destroyed();
00864
00870 virtual void* getObject(const String& name) const;
00871
00876 virtual const String& toString() const;
00877
00882 Mutex* mutex() const;
00883
00888 static Mutex& commonMutex();
00889
00895 bool connect(DataEndpoint* peer);
00896
00901 bool disconnect();
00902
00907 void setSource(DataSource* source = 0);
00908
00913 inline DataSource* getSource() const
00914 { return m_source; }
00915
00920 void setConsumer(DataConsumer* consumer = 0);
00921
00926 inline DataConsumer* getConsumer() const
00927 { return m_consumer; }
00928
00934 void setPeerRecord(DataConsumer* consumer = 0);
00935
00940 inline DataConsumer* getPeerRecord() const
00941 { return m_peerRecord; }
00942
00948 void setCallRecord(DataConsumer* consumer = 0);
00949
00954 inline DataConsumer* getCallRecord() const
00955 { return m_callRecord; }
00956
00962 bool addSniffer(DataConsumer* sniffer);
00963
00969 bool delSniffer(DataConsumer* sniffer);
00970
00976 inline DataConsumer* getSniffer(const String& name)
00977 { return static_cast<DataConsumer*>(m_sniffers[name]); }
00978
00982 void clearSniffers();
00983
00988 inline DataEndpoint* getPeer() const
00989 { return m_peer; }
00990
00995 inline CallEndpoint* getCall() const
00996 { return m_call; }
00997
01002 inline const String& name() const
01003 { return m_name; }
01004
01005 protected:
01011 virtual bool nativeConnect(DataEndpoint* peer)
01012 { return false; }
01013
01014 private:
01015 String m_name;
01016 DataSource* m_source;
01017 DataConsumer* m_consumer;
01018 DataEndpoint* m_peer;
01019 CallEndpoint* m_call;
01020 DataConsumer* m_peerRecord;
01021 DataConsumer* m_callRecord;
01022 ObjList m_sniffers;
01023 };
01024
01029 class YATE_API CallEndpoint : public RefObject
01030 {
01031 friend class DataEndpoint;
01032
01033 private:
01034 CallEndpoint* m_peer;
01035 String m_id;
01036
01037 protected:
01038 ObjList m_data;
01039 Mutex* m_mutex;
01040
01041 public:
01045 virtual void destroyed();
01046
01052 virtual void* getObject(const String& name) const;
01053
01058 virtual const String& toString() const
01059 { return m_id; }
01060
01065 inline const String& id() const
01066 { return m_id; }
01067
01072 inline CallEndpoint* getPeer() const
01073 { return m_peer; }
01074
01079 inline const String& getPeerId() const
01080 { return m_peer ? m_peer->id() : String::empty(); }
01081
01086 inline Mutex* mutex() const
01087 { return m_mutex; }
01088
01093 static Mutex& commonMutex();
01094
01102 bool connect(CallEndpoint* peer, const char* reason = 0, bool notify = true);
01103
01110 inline bool disconnect(const char* reason = 0, bool notify = true)
01111 { return disconnect(false,reason,notify); }
01112
01118 DataEndpoint* getEndpoint(const char* type = "audio") const;
01119
01125 DataEndpoint* setEndpoint(const char* type = "audio");
01126
01131 void clearEndpoint(const char* type = 0);
01132
01138 void setSource(DataSource* source = 0, const char* type = "audio");
01139
01145 DataSource* getSource(const char* type = "audio") const;
01146
01152 void setConsumer(DataConsumer* consumer = 0, const char* type = "audio");
01153
01159 DataConsumer* getConsumer(const char* type = "audio") const;
01160
01161 protected:
01165 CallEndpoint(const char* id = 0);
01166
01171 virtual void connected(const char* reason) { }
01172
01178 virtual void disconnected(bool final, const char* reason) { }
01179
01186 void setPeer(CallEndpoint* peer, const char* reason = 0, bool notify = true);
01187
01192 void setEndpoint(DataEndpoint* endPoint);
01193
01198 virtual void setId(const char* newId);
01199
01200 private:
01201 bool disconnect(bool final, const char* reason, bool notify);
01202 };
01203
01208 class YATE_API Module : public Plugin, public Mutex, public MessageReceiver, public DebugEnabler
01209 {
01210 private:
01211 bool m_init;
01212 int m_relays;
01213 String m_name;
01214 String m_type;
01215 Regexp m_filter;
01216 u_int64_t m_changed;
01217 static unsigned int s_delay;
01218
01219 public:
01225 virtual void* getObject(const String& name) const;
01226
01231 inline const String& name() const
01232 { return m_name; }
01233
01238 inline const String& type() const
01239 { return m_type; }
01240
01245 void changed();
01246
01251 inline static unsigned int updateDelay()
01252 { return s_delay; }
01253
01258 inline static void updateDelay(unsigned int delay)
01259 { s_delay = delay; }
01260
01265 inline bool filterInstalled() const
01266 { return !m_filter.null(); }
01267
01273 bool filterDebug(const String& item) const;
01274
01275 protected:
01279 enum {
01280
01281 Status = 0x00000001,
01282 Timer = 0x00000002,
01283 Level = 0x00000004,
01284 Command = 0x00000008,
01285 Help = 0x00000010,
01286 Halt = 0x00000020,
01287 Route = 0x00000040,
01288
01289 Execute = 0x00000100,
01290 Drop = 0x00000200,
01291
01292 Locate = 0x00000400,
01293 Masquerade = 0x00000800,
01294 Ringing = 0x00001000,
01295 Answered = 0x00002000,
01296 Tone = 0x00004000,
01297 Text = 0x00008000,
01298 Progress = 0x00010000,
01299 Update = 0x00020000,
01300 Transfer = 0x00040000,
01301
01302 PubLast = 0x0fffffff,
01303
01304 Private = 0x10000000
01305 } RelayID;
01306
01312 static const char* messageName(int id);
01313
01319 Module(const char* name, const char* type = 0);
01320
01324 virtual ~Module();
01325
01329 virtual void initialize();
01330
01334 void setup();
01335
01342 bool installRelay(int id, unsigned priority = 100);
01343
01350 bool installRelay(const char* name, unsigned priority = 100);
01351
01358 virtual bool received(Message &msg, int id);
01359
01364 virtual void genUpdate(Message& msg);
01365
01370 virtual void msgTimer(Message& msg);
01371
01376 virtual void msgStatus(Message& msg);
01377
01383 virtual bool msgRoute(Message& msg);
01384
01391 virtual bool msgCommand(Message& msg);
01392
01397 virtual void statusModule(String& str);
01398
01403 virtual void statusParams(String& str);
01404
01409 virtual void statusDetail(String& str);
01410
01417 virtual bool commandExecute(String& retVal, const String& line);
01418
01426 virtual bool commandComplete(Message& msg, const String& partLine, const String& partWord);
01427
01433 virtual bool setDebug(Message& msg, const String& target);
01434
01435 private:
01436 Module();
01437 static TokenDict s_messages[];
01438 bool installRelay(const char* name, int id, unsigned priority);
01439 };
01440
01445 class YATE_API Channel : public CallEndpoint, public DebugEnabler
01446 {
01447 friend class Driver;
01448 friend class Router;
01449
01450 private:
01451 Driver* m_driver;
01452 bool m_outgoing;
01453 u_int64_t m_timeout;
01454 u_int64_t m_maxcall;
01455 mutable unsigned int m_sequence;
01456
01457 protected:
01458 String m_status;
01459 String m_address;
01460 String m_targetid;
01461 String m_billid;
01462 bool m_answered;
01463
01464 public:
01468 virtual ~Channel();
01469
01475 virtual void* getObject(const String& name) const;
01476
01482 virtual void complete(Message& msg, bool minimal = false) const;
01483
01491 Message* message(const char* name, bool minimal = false, bool data = false);
01492
01503 Message* message(const char* name, const NamedList* original, const char* params = 0, bool minimal = false, bool data = false);
01504
01515 inline Message* message(const char* name, const NamedList& original, const char* params = 0, bool minimal = false, bool data = false)
01516 { return message(name,&original,params,minimal,data); }
01517
01523 virtual bool msgProgress(Message& msg);
01524
01530 virtual bool msgRinging(Message& msg);
01531
01537 virtual bool msgAnswered(Message& msg);
01538
01545 virtual bool msgTone(Message& msg, const char* tone);
01546
01553 virtual bool msgText(Message& msg, const char* text);
01554
01561 virtual bool msgDrop(Message& msg, const char* reason);
01562
01568 virtual bool msgTransfer(Message& msg);
01569
01575 virtual bool msgUpdate(Message& msg);
01576
01582 virtual bool msgMasquerade(Message& msg);
01583
01588 virtual void msgStatus(Message& msg);
01589
01595 virtual void checkTimers(Message& msg, const Time& tmr);
01596
01603 virtual bool callPrerouted(Message& msg, bool handled);
01604
01610 virtual bool callRouted(Message& msg);
01611
01616 virtual void callAccept(Message& msg);
01617
01624 virtual void callRejected(const char* error, const char* reason = 0, const Message* msg = 0);
01625
01631 virtual void callConnect(Message& msg);
01632
01637 virtual bool setDebug(Message& msg);
01638
01643 inline const String& status() const
01644 { return m_status; }
01645
01650 inline const String& address() const
01651 { return m_address; }
01652
01657 inline bool isOutgoing() const
01658 { return m_outgoing; }
01659
01664 inline bool isIncoming() const
01665 { return !m_outgoing; }
01666
01671 inline bool isAnswered() const
01672 { return m_answered; }
01673
01678 const char* direction() const;
01679
01684 inline Driver* driver() const
01685 { return m_driver; }
01686
01691 inline u_int64_t timeout() const
01692 { return m_timeout; }
01693
01698 inline void timeout(u_int64_t tout)
01699 { m_timeout = tout; }
01700
01705 inline u_int64_t maxcall() const
01706 { return m_maxcall; }
01707
01712 inline void maxcall(u_int64_t tout)
01713 { m_maxcall = tout; }
01714
01719 inline void setMaxcall(const Message& msg)
01720 { setMaxcall(&msg); }
01721
01726 void setMaxcall(const Message* msg);
01727
01733 inline const String& targetid() const
01734 { return m_targetid; }
01735
01741 inline const String& billid() const
01742 { return m_billid; }
01743
01750 bool startRouter(Message* msg);
01751
01756 static unsigned int allocId();
01757
01762 void filterDebug(const String& item);
01763
01764 protected:
01768 Channel(Driver* driver, const char* id = 0, bool outgoing = false);
01769
01773 Channel(Driver& driver, const char* id = 0, bool outgoing = false);
01774
01779 void cleanup();
01780
01784 void dropChan();
01785
01790 virtual void zeroRefs();
01791
01796 virtual void connected(const char* reason);
01797
01803 virtual void disconnected(bool final, const char* reason);
01804
01809 virtual void setId(const char* newId);
01810
01816 void status(const char* newstat);
01817
01822 virtual void statusParams(String& str);
01823
01828 inline void setOutgoing(bool outgoing = true)
01829 { m_outgoing = outgoing; }
01830
01837 bool dtmfInband(const char* tone);
01838
01845 bool toneDetect(const char* sniffer = 0);
01846
01847 private:
01848 void init();
01849 Channel();
01850 };
01851
01856 class YATE_API Driver : public Module
01857 {
01858 friend class Router;
01859 friend class Channel;
01860
01861 private:
01862 bool m_init;
01863 bool m_varchan;
01864 String m_prefix;
01865 ObjList m_chans;
01866 int m_routing;
01867 int m_routed;
01868 int m_total;
01869 unsigned int m_nextid;
01870 int m_timeout;
01871 int m_maxroute;
01872 int m_maxchans;
01873
01874 public:
01880 virtual void* getObject(const String& name) const;
01881
01886 inline const String& prefix() const
01887 { return m_prefix; }
01888
01893 inline bool varchan() const
01894 { return m_varchan; }
01895
01900 inline ObjList& channels()
01901 { return m_chans; }
01902
01908 virtual Channel* find(const String& id) const;
01909
01914 virtual bool isBusy() const;
01915
01920 virtual void dropAll(Message &msg);
01921
01927 virtual bool canAccept(bool routers = true);
01928
01933 virtual bool canRoute();
01934
01939 unsigned int nextid();
01940
01945 inline unsigned int lastid() const
01946 { return m_nextid; }
01947
01952 inline int timeout() const
01953 { return m_timeout; }
01954
01959 inline int routing() const
01960 { return m_routing; }
01961
01966 inline int routed() const
01967 { return m_routed; }
01968
01973 inline int total() const
01974 { return m_total; }
01975
01976 protected:
01982 Driver(const char* name, const char* type = 0);
01983
01987 virtual void initialize();
01988
01994 void setup(const char* prefix = 0, bool minimal = false);
01995
02002 virtual bool received(Message &msg, int id);
02003
02008 virtual void genUpdate(Message& msg);
02009
02016 virtual bool msgExecute(Message& msg, String& dest) = 0;
02017
02025 virtual bool commandComplete(Message& msg, const String& partLine, const String& partWord);
02026
02031 virtual void statusModule(String& str);
02032
02037 virtual void statusParams(String& str);
02038
02043 virtual void statusDetail(String& str);
02044
02050 virtual bool setDebug(Message& msg, const String& target);
02051
02055 virtual void loadLimits();
02056
02061 inline void varchan(bool variable)
02062 { m_varchan = variable; }
02063
02068 inline void timeout(int tout)
02069 { m_timeout = tout; }
02070
02075 inline void maxRoute(int ncalls)
02076 { m_maxroute = ncalls; }
02077
02082 inline void maxChans(int ncalls)
02083 { m_maxchans = ncalls; }
02084
02085 private:
02086 Driver();
02087 };
02088
02093 class YATE_API Router : public Thread
02094 {
02095 private:
02096 Driver* m_driver;
02097 String m_id;
02098 Message* m_msg;
02099
02100 public:
02107 Router(Driver* driver, const char* id, Message* msg);
02108
02112 virtual void run();
02113
02118 virtual bool route();
02119
02123 virtual void cleanup();
02124
02125 protected:
02130 const String& id() const
02131 { return m_id; }
02132 };
02133
02139 YATE_API bool isE164(const char* str);
02140
02141 };
02142
02143 #endif
02144
02145