1 /** 2 * yatengine.h 3 * This file is part of the YATE Project http://YATE.null.ro 4 * 5 * Engine, plugins and messages related classes 6 * 7 * Yet Another Telephony Engine - a fully featured software PBX and IVR 8 * Copyright (C) 2004-2014 Null Team 9 * 10 * This software is distributed under multiple licenses; 11 * see the COPYING file in the main directory for licensing 12 * information for this specific distribution. 13 * 14 * This use of this software may be subject to additional restrictions. 15 * See the LEGAL file in the main directory for details. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #ifndef __YATENGINE_H 23 #define __YATENGINE_H 24 25 #ifndef __cplusplus 26 #error C++ is required 27 #endif 28 29 #include <yateclass.h> 30 31 /** 32 * Holds all Telephony Engine related classes. 33 */ 34 namespace TelEngine { 35 36 /** 37 * A class for parsing and quickly accessing INI style configuration files 38 * @short Configuration file handling 39 */ 40 class YATE_API Configuration : public String 41 { 42 YNOCOPY(Configuration); // no automatic copies please 43 public: 44 /** 45 * Create an empty configuration 46 */ 47 Configuration(); 48 49 /** 50 * Create a configuration from a file 51 * @param filename Name of file to initialize from 52 * @param warn True to warn if the configuration could not be loaded 53 */ 54 explicit Configuration(const char* filename, bool warn = true); 55 56 /** 57 * Assignment from string operator 58 */ 59 inline Configuration& operator=(const String& value) 60 { String::operator=(value); return *this; } 61 62 /** 63 * Get the number of sections 64 * @return Count of sections 65 */ sections()66 inline unsigned int sections() const 67 { return m_sections.length(); } 68 69 /** 70 * Get the number of non null sections 71 * @return Count of sections 72 */ count()73 inline unsigned int count() const 74 { return m_sections.count(); } 75 76 /** 77 * Retrieve an entire section 78 * @param index Index of the section 79 * @return The section's content or NULL if no such section 80 */ 81 NamedList* getSection(unsigned int index) const; 82 83 /** 84 * Retrieve an entire section 85 * @param sect Name of the section 86 * @return The section's content or NULL if no such section 87 */ 88 NamedList* getSection(const String& sect) const; 89 90 /** 91 * Locate a key/value pair in the section. 92 * @param sect Name of the section 93 * @param key Name of the key in section 94 * @return A pointer to the key/value pair or NULL. 95 */ 96 NamedString* getKey(const String& sect, const String& key) const; 97 98 /** 99 * Retrieve the value of a key in a section. 100 * @param sect Name of the section 101 * @param key Name of the key in section 102 * @param defvalue Default value to return if not found 103 * @return The string contained in the key or the default 104 */ 105 const char* getValue(const String& sect, const String& key, const char* defvalue = 0) const; 106 107 /** 108 * Retrieve the numeric value of a key in a section. 109 * @param sect Name of the section 110 * @param key Name of the key in section 111 * @param defvalue Default value to return if not found 112 * @param minvalue Minimum value allowed for the parameter 113 * @param maxvalue Maximum value allowed for the parameter 114 * @param clamp Control the out of bound values: true to adjust to the nearest 115 * bound, false to return the default value 116 * @return The number contained in the key or the default 117 */ 118 int getIntValue(const String& sect, const String& key, int defvalue = 0, 119 int minvalue = INT_MIN, int maxvalue = INT_MAX, bool clamp = true) const; 120 121 /** 122 * Retrieve the numeric value of a key in a section trying first a table lookup. 123 * @param sect Name of the section 124 * @param key Name of the key in section 125 * @param tokens A pointer to an array of tokens to try to lookup 126 * @param defvalue Default value to return if not found 127 * @return The number contained in the key or the default 128 */ 129 int getIntValue(const String& sect, const String& key, const TokenDict* tokens, int defvalue = 0) const; 130 131 /** 132 * Retrieve the 64-bit numeric value of a key in a section. 133 * @param sect Name of the section 134 * @param key Name of the key in section 135 * @param defvalue Default value to return if not found 136 * @param minvalue Minimum value allowed for the parameter 137 * @param maxvalue Maximum value allowed for the parameter 138 * @param clamp Control the out of bound values: true to adjust to the nearest 139 * bound, false to return the default value 140 * @return The number contained in the key or the default 141 */ 142 int64_t getInt64Value(const String& sect, const String& key, int64_t defvalue = 0, 143 int64_t minvalue = LLONG_MIN, int64_t maxvalue = LLONG_MAX, bool clamp = true) const; 144 145 /** 146 * Retrieve the floating point value of a key in a section. 147 * @param sect Name of the section 148 * @param key Name of the key in section 149 * @param defvalue Default value to return if not found 150 * @return The numeric value contained in the key or the default 151 */ 152 double getDoubleValue(const String& sect, const String& key, double defvalue = 0.0) const; 153 154 /** 155 * Retrieve the boolean value of a key in a section. 156 * @param sect Name of the section 157 * @param key Name of the key in section 158 * @param defvalue Default value to return if not found 159 * @return The boolean value contained in the key or the default 160 */ 161 bool getBoolValue(const String& sect, const String& key, bool defvalue = false) const; 162 163 /** 164 * Deletes an entire section 165 * @param sect Name of section to delete, NULL to delete all 166 */ 167 void clearSection(const char* sect = 0); 168 169 /** 170 * Makes sure a section with a given name exists, creates if required 171 * @param sect Name of section to check or create 172 * @return The section's content or NULL if no such section 173 */ 174 NamedList* createSection(const String& sect); 175 176 /** 177 * Deletes a key/value pair 178 * @param sect Name of section 179 * @param key Name of the key to delete 180 */ 181 void clearKey(const String& sect, const String& key); 182 183 /** 184 * Add the value of a key in a section. 185 * @param sect Name of the section, will be created if missing 186 * @param key Name of the key to add in the section 187 * @param value Value to set in the key 188 */ 189 void addValue(const String& sect, const char* key, const char* value = 0); 190 191 /** 192 * Set the value of a key in a section. 193 * @param sect Name of the section, will be created if missing 194 * @param key Name of the key in section, will be created if missing 195 * @param value Value to set in the key 196 */ 197 void setValue(const String& sect, const char* key, const char* value = 0); 198 199 /** 200 * Set the numeric value of a key in a section. 201 * @param sect Name of the section, will be created if missing 202 * @param key Name of the key in section, will be created if missing 203 * @param value Value to set in the key 204 */ 205 void setValue(const String& sect, const char* key, int value); 206 207 /** 208 * Set the boolean value of a key in a section. 209 * @param sect Name of the section, will be created if missing 210 * @param key Name of the key in section, will be created if missing 211 * @param value Value to set in the key 212 */ 213 void setValue(const String& sect, const char* key, bool value); 214 215 /** 216 * Load the configuration from file 217 * @param warn True to also warn if the configuration could not be loaded 218 * @return True if successfull, false for failure 219 */ 220 bool load(bool warn = true); 221 222 /** 223 * Save the configuration to file 224 * @return True if successfull, false for failure 225 */ 226 bool save() const; 227 228 private: 229 ObjList *getSectHolder(const String& sect) const; 230 ObjList *makeSectHolder(const String& sect); 231 bool loadFile(const char* file, String sect, unsigned int depth, bool warn); 232 ObjList m_sections; 233 }; 234 235 /** 236 * Class that implements atomic / locked access and operations to its shared variables 237 * @short Atomic access and operations to shared variables 238 */ 239 class YATE_API SharedVars : public Mutex 240 { 241 public: 242 /** 243 * Constructor 244 */ SharedVars()245 inline SharedVars() 246 : Mutex(false,"SharedVars"), m_vars("") 247 { } 248 249 /** 250 * Get the string value of a variable 251 * @param name Name of the variable 252 * @param rval String to return the value into 253 */ 254 void get(const String& name, String& rval); 255 256 /** 257 * Set the string value of a variable 258 * @param name Name of the variable to set 259 * @param val New value to assign to a variable 260 */ 261 void set(const String& name, const char* val); 262 263 /** 264 * Create and set a variable only if the variable is not already set 265 * @param name Name of the variable to set 266 * @param val New value to assign to a variable 267 * @return True if a new variable was created 268 */ 269 bool create(const String& name, const char* val = 0); 270 271 /** 272 * Clear a variable 273 * @param name Name of the variable to clear 274 */ 275 void clear(const String& name); 276 277 /** 278 * Check if a variable exists 279 * @param name Name of the variable 280 * @return True if the variable exists 281 */ 282 bool exists(const String& name); 283 284 /** 285 * Atomically increment a variable as unsigned integer 286 * @param name Name of the variable 287 * @param wrap Value to wrap around at, zero disables 288 * @return Value of the variable before increment, zero if it was not defined or not numeric 289 */ 290 unsigned int inc(const String& name, unsigned int wrap = 0); 291 292 /** 293 * Atomically decrement a variable as unsigned integer 294 * @param name Name of the variable 295 * @param wrap Value to wrap around at, zero disables (stucks at zero) 296 * @return Value of the variable after decrement, zero if it was not defined or not numeric 297 */ 298 unsigned int dec(const String& name, unsigned int wrap = 0); 299 300 private: 301 NamedList m_vars; 302 }; 303 304 class MessageDispatcher; 305 class MessageRelay; 306 class Engine; 307 308 /** 309 * This class holds the messages that are moved around in the engine. 310 * @short A message container class 311 */ 312 class YATE_API Message : public NamedList 313 { 314 friend class MessageDispatcher; 315 public: 316 /** 317 * Creates a new message. 318 * 319 * @param name Name of the message - must not be NULL or empty 320 * @param retval Default return value 321 * @param broadcast Broadcast flag, true if handling the mesage must not stop it 322 */ 323 explicit Message(const char* name, const char* retval = 0, bool broadcast = false); 324 325 /** 326 * Copy constructor. 327 * Note that user data and notification are not copied 328 * @param original Message we are copying from 329 */ 330 Message(const Message& original); 331 332 /** 333 * Copy constructor that can alter the broadcast flag. 334 * Note that user data and notification are not copied 335 * @param original Message we are copying from 336 * @param broadcast Broadcast flag, true if handling the mesage must not stop it 337 */ 338 Message(const Message& original, bool broadcast); 339 340 /** 341 * Destruct the message and dereferences any user data 342 */ 343 ~Message(); 344 345 /** 346 * Get a pointer to a derived class given that class name 347 * @param name Name of the class we are asking for 348 * @return Pointer to the requested class or NULL if this object doesn't implement it 349 */ 350 virtual void* getObject(const String& name) const; 351 352 /** 353 * Retrieve a reference to the value returned by the message. 354 * @return A reference to the value the message will return 355 */ retValue()356 inline String& retValue() 357 { return m_return; } 358 359 /** 360 * Retrieve a const reference to the value returned by the message. 361 * @return A reference to the value the message will return 362 */ retValue()363 inline const String& retValue() const 364 { return m_return; } 365 366 /** 367 * Retrieve the object associated with the message 368 * @return Pointer to arbitrary user RefObject 369 */ userData()370 inline RefObject* userData() const 371 { return m_data; } 372 373 /** 374 * Set obscure data associated with the message. 375 * The user data is reference counted to avoid stray pointers. 376 * Note that setting new user data will disable any notification. 377 * @param data Pointer to arbitrary user data 378 */ 379 void userData(RefObject* data); 380 381 /** 382 * Get a pointer to a derived class of user data given that class name 383 * @param name Name of the class we are asking for 384 * @return Pointer to the requested class or NULL if user object id NULL or doesn't implement it 385 */ userObject(const String & name)386 inline void* userObject(const String& name) const 387 { return m_data ? m_data->getObject(name) : 0; } 388 389 390 /** 391 * Enable or disable notification of any @ref MessageNotifier that was set 392 * as user data. This method must be called after userData() 393 * @param notify True to have the message call the notifier 394 */ 395 inline void setNotify(bool notify = true) 396 { m_notify = notify; } 397 398 /** 399 * Retrieve the broadcast flag 400 * @return True if the message is a broadcast (handling does not stop it) 401 */ broadcast()402 inline bool broadcast() const 403 { return m_broadcast; } 404 405 /** 406 * Retrieve a reference to the creation time of the message. 407 * @return A reference to the @ref Time when the message was created 408 */ msgTime()409 inline Time& msgTime() 410 { return m_time; } 411 412 /** 413 * Retrieve a const reference to the creation time of the message. 414 * @return A reference to the @ref Time when the message was created 415 */ msgTime()416 inline const Time& msgTime() const 417 { return m_time; } 418 419 /** 420 * Name assignment operator 421 */ 422 inline Message& operator=(const char* value) 423 { String::operator=(value); return *this; } 424 425 /** 426 * Encode the message into a string adequate for sending for processing 427 * to an external communication interface 428 * @param id Unique identifier to add to the string 429 */ 430 String encode(const char* id) const; 431 432 /** 433 * Encode the message into a string adequate for sending as answer 434 * to an external communication interface 435 * @param received True if message was processed locally 436 * @param id Unique identifier to add to the string 437 */ 438 String encode(bool received, const char* id) const; 439 440 /** 441 * Decode a string from an external communication interface for processing 442 * in the engine. The message is modified accordingly. 443 * @param str String to decode 444 * @param id A String object in which the identifier is stored 445 * @return -2 for success, -1 if the string was not a text form of a 446 * message, index of first erroneous character if failed 447 */ 448 int decode(const char* str, String& id); 449 450 /** 451 * Decode a string from an external communication interface that is an 452 * answer to a specific external processing request. 453 * @param str String to decode 454 * @param received Pointer to variable to store the dispatch return value 455 * @param id The identifier expected 456 * @return -2 for success, -1 if the string was not the expected answer, 457 * index of first erroneous character if failed 458 */ 459 int decode(const char* str, bool& received, const char* id); 460 461 protected: 462 /** 463 * Notify the message it has been dispatched. 464 * The default behaviour is to call the dispatched() method of the user 465 * data if it implements @ref MessageNotifier 466 * @param accepted True if one handler accepted the message 467 */ 468 virtual void dispatched(bool accepted); 469 470 private: 471 Message(); // no default constructor please 472 Message& operator=(const Message& value); // no assignment please 473 String m_return; 474 Time m_time; 475 RefObject* m_data; 476 bool m_notify; 477 bool m_broadcast; 478 void commonEncode(String& str) const; 479 int commonDecode(const char* str, int offs); 480 }; 481 482 /** 483 * The purpose of this class is to hold a message received method that is 484 * called for matching messages. It holds as well the matching criteria 485 * and priority among other handlers. 486 * @short A message handler 487 */ 488 class YATE_API MessageHandler : public String 489 { 490 friend class MessageDispatcher; 491 YNOCOPY(MessageHandler); // no automatic copies please 492 public: 493 /** 494 * Creates a new message handler. 495 * @param name Name of the handled message - may be NULL 496 * @param priority Priority of the handler, 0 = top 497 * @param trackName Name to be used in handler tracking 498 * @param addPriority True to append :priority to trackName 499 */ 500 explicit MessageHandler(const char* name, unsigned priority = 100, 501 const char* trackName = 0, bool addPriority = true); 502 503 /** 504 * Handler destructor. 505 */ 506 virtual ~MessageHandler(); 507 508 /** 509 * Destroys the object, performs cleanup first 510 */ 511 virtual void destruct(); 512 513 /** 514 * This method is called whenever the registered name matches the message. 515 * @param msg The received message 516 * @return True to stop processing, false to try other handlers 517 */ 518 virtual bool received(Message& msg) = 0; 519 520 /** 521 * Find out the priority of the handler 522 * @return Stored priority of the handler, 0 = top 523 */ priority()524 inline unsigned priority() const 525 { return m_priority; } 526 527 /** 528 * Retrieve the tracking name of this handler 529 * @return Name that is to be used in tracking operation 530 */ trackName()531 inline const String& trackName() const 532 { return m_trackName; } 533 534 /** 535 * Set a new tracking name for this handler. 536 * Works only if the handler was not yet inserted into a dispatcher 537 * @param name Name that is to be used in tracking operation 538 */ trackName(const char * name)539 inline void trackName(const char* name) 540 { if (!m_dispatcher) m_trackName = name; } 541 542 /** 543 * Retrive the objects counter associated to this handler 544 * @return Pointer to handler's objects counter or NULL 545 */ objectsCounter()546 inline NamedCounter* objectsCounter() const 547 { return m_counter; } 548 549 /** 550 * Retrieve the filter (if installed) associated to this handler 551 */ filter()552 inline const NamedString* filter() const 553 { return m_filter; } 554 555 /** 556 * Retrieve the Regexp filter (if installed) associated to this handler 557 */ filterRegexp()558 inline const Regexp* filterRegexp() const 559 { return m_filterRegexp; } 560 561 /** 562 * Set a filter for this handler 563 * @param filter Pointer to the filter to install, will be owned and 564 * destroyed by the handler. The filter may be a NamedPointer carrying a Regexp 565 */ 566 void setFilter(NamedString* filter); 567 568 /** 569 * Set a filter for this handler 570 * @param name Name of the parameter to filter 571 * @param value Value of the parameter to filter 572 */ setFilter(const char * name,const char * value)573 inline void setFilter(const char* name, const char* value) 574 { setFilter(new NamedString(name,value)); } 575 576 /** 577 * Remove and destroy any filter associated to this handler 578 */ 579 void clearFilter(); 580 581 protected: 582 /** 583 * Remove the handler from its dispatcher, remove any installed filter. 584 * This method is called internally from destruct and the destructor 585 */ 586 void cleanup(); 587 588 /** 589 * Internal use received function, do not call or override! 590 * @param msg The received message 591 * @return True if message was processed 592 */ 593 virtual bool receivedInternal(Message& msg); 594 595 /** 596 * Internal use handler unlock, do not call! 597 */ 598 void safeNowInternal(); 599 600 private: 601 String m_trackName; 602 unsigned m_priority; 603 int m_unsafe; 604 MessageDispatcher* m_dispatcher; 605 NamedString* m_filter; 606 Regexp* m_filterRegexp; 607 NamedCounter* m_counter; 608 }; 609 610 /** 611 * A multiple message receiver to be invoked by a message relay 612 * @short A multiple message receiver 613 */ 614 class YATE_API MessageReceiver : public GenObject 615 { 616 public: 617 /** 618 * This method is called from the message relay. 619 * @param msg The received message 620 * @param id The identifier with which the relay was created 621 * @return True to stop processing, false to try other handlers 622 */ 623 virtual bool received(Message& msg, int id) = 0; 624 }; 625 626 /** 627 * A message handler that allows to relay several messages to a single receiver 628 * @short A message handler relay 629 */ 630 class YATE_API MessageRelay : public MessageHandler 631 { 632 YNOCOPY(MessageRelay); // no automatic copies please 633 public: 634 /** 635 * Creates a new message relay. 636 * @param name Name of the handled message - may be NULL 637 * @param receiver Receiver of th relayed messages 638 * @param id Numeric identifier to pass to receiver 639 * @param priority Priority of the handler, 0 = top 640 * @param trackName Name to be used in handler tracking 641 * @param addPriority True to append :priority to trackName 642 */ 643 inline MessageRelay(const char* name, MessageReceiver* receiver, int id, 644 int priority = 100, const char* trackName = 0, bool addPriority = true) MessageHandler(name,priority,trackName,addPriority)645 : MessageHandler(name,priority,trackName,addPriority), 646 m_receiver(receiver), m_id(id) 647 { } 648 649 /** 650 * This method is not called from MessageHandler through polymorphism 651 * and should not be used or reimplemented. 652 * @param msg The received message 653 * @return True if the receiver exists and has handled the message 654 */ received(Message & msg)655 virtual bool received(Message& msg) 656 { return m_receiver && m_receiver->received(msg,m_id); } 657 658 /** 659 * Get the ID of this message relay 660 * @return Numeric identifier passed to receiver 661 */ id()662 inline int id() const 663 { return m_id; } 664 665 /** 666 * Internal use received function, do not call or override! 667 * @param msg The received message 668 * @return True if message was processed 669 */ 670 virtual bool receivedInternal(Message& msg); 671 672 private: 673 MessageReceiver* m_receiver; 674 int m_id; 675 }; 676 677 /** 678 * An abstract class to implement hook methods called after any message has 679 * been dispatched. If an object implementing MessageNotifier is set as user 680 * data in a @ref Message then the dispatched() method will be called. 681 * @short Post-dispatching message hook 682 */ 683 class YATE_API MessageNotifier 684 { 685 public: 686 /** 687 * Destructor. Keeps compiler form complaining. 688 */ 689 virtual ~MessageNotifier(); 690 691 /** 692 * This method is called after a message was dispatched. 693 * @param msg The already dispatched message message 694 * @param handled True if a handler claimed to have handled the message 695 */ 696 virtual void dispatched(const Message& msg, bool handled) = 0; 697 }; 698 699 /** 700 * An abstract message notifier that can be inserted in a @ref MessageDispatcher 701 * to implement hook methods called after any message has been dispatched. 702 * No new methods are provided - we only need the multiple inheritance. 703 * @short Post-dispatching message hook that can be added to a list 704 */ 705 class YATE_API MessagePostHook : public RefObject, public MessageNotifier 706 { 707 }; 708 709 /** 710 * The dispatcher class is a hub that holds a list of handlers to be called 711 * for the messages that pass trough the hub. It can also handle a queue of 712 * messages that are typically dispatched by a separate thread. 713 * @short A message dispatching hub 714 */ 715 class YATE_API MessageDispatcher : public GenObject, public Mutex 716 { 717 friend class Engine; 718 YNOCOPY(MessageDispatcher); // no automatic copies please 719 public: 720 /** 721 * Creates a new message dispatcher. 722 * @param trackParam Name of the parameter used in tracking handlers 723 */ 724 MessageDispatcher(const char* trackParam = 0); 725 726 /** 727 * Destroys the dispatcher and the installed handlers. 728 */ 729 ~MessageDispatcher(); 730 731 /** 732 * Retrieve the tracker parameter name 733 * @return Name of the parameter used to track message dispatching 734 */ trackParam()735 inline const String& trackParam() const 736 { return m_trackParam; } 737 738 /** 739 * Installs a handler in the dispatcher. 740 * The handlers are installed in ascending order of their priorities. 741 * There is NO GUARANTEE on the order of handlers with equal priorities 742 * although for avoiding uncertainity such handlers are sorted by address. 743 * @param handler A pointer to the handler to install 744 * @return True on success, false on failure 745 */ 746 bool install(MessageHandler* handler); 747 748 /** 749 * Uninstalls a handler from the dispatcher. 750 * @param handler A pointer to the handler to uninstall 751 * @return True on success, false on failure 752 */ 753 bool uninstall(MessageHandler* handler); 754 755 /** 756 * Synchronously dispatch a message to the installed handlers. 757 * Handlers matching the message name and filter parameter are called in 758 * their installed order (based on priority) until one returns true. 759 * If the message has the broadcast flag set all matching handlers are 760 * called and the return value is true if any handler returned true. 761 * Note that in some cases when a handler is removed from the list 762 * other handlers with equal priority may be called twice. 763 * @param msg The message to dispatch 764 * @return True if one handler accepted it, false if all ignored 765 */ 766 bool dispatch(Message& msg); 767 768 /** 769 * Put a message in the waiting queue for asynchronous dispatching 770 * @param msg The message to enqueue, will be destroyed after dispatching 771 * @return True if successfully queued, false otherwise 772 */ 773 bool enqueue(Message* msg); 774 775 /** 776 * Dispatch all messages from the waiting queue 777 */ 778 void dequeue(); 779 780 /** 781 * Dispatch one message from the waiting queue 782 * @return True if success, false if the queue is empty 783 */ 784 bool dequeueOne(); 785 786 /** 787 * Set a limit to generate warning when a message took too long to dispatch 788 * @param usec Warning time limit in microseconds, zero to disable 789 */ warnTime(u_int64_t usec)790 inline void warnTime(u_int64_t usec) 791 { m_warnTime = usec; } 792 793 /** 794 * Clear all the message handlers and post-dispatch hooks 795 */ clear()796 inline void clear() 797 { m_handlers.clear(); m_hookAppend = &m_hooks; m_hooks.clear(); } 798 799 /** 800 * Check if there is at least one message in the queue 801 * @return True if the queue holds at least one message 802 */ hasMessages()803 inline bool hasMessages() const 804 { return m_messages.get() || m_messages.next(); } 805 806 /** 807 * Check if there is at least one handler installed 808 * @return True if at least one handler is installed 809 */ hasHandlers()810 inline bool hasHandlers() const 811 { return m_handlers.get() || m_handlers.next(); } 812 813 /** 814 * Check if there is at least one message hook installed 815 * @return True if at least one hook is installed 816 */ hasHooks()817 inline bool hasHooks() const 818 { return m_hooks.get() || m_hooks.next(); } 819 820 /** 821 * Get the number of messages waiting in the queue 822 * @return Count of messages in the queue 823 */ 824 unsigned int messageCount(); 825 826 /** 827 * Get the number of handlers in this dispatcher 828 * @return Count of handlers 829 */ 830 unsigned int handlerCount(); 831 832 /** 833 * Get the number of post-handling hooks in this dispatcher 834 * @return Count of hooks 835 */ 836 unsigned int postHookCount(); 837 838 /** 839 * Get the total number of enqueued messages 840 * @return Count of enqueued messages 841 */ enqueueCount()842 u_int64_t enqueueCount() const 843 { return m_enqueueCount; } 844 845 /** 846 * Get the total number of dequeued messages 847 * @return Count of dequeued messages 848 */ dequeueCount()849 u_int64_t dequeueCount() const 850 { return m_dequeueCount; } 851 852 /** 853 * Get the total number of dispatched messages 854 * @return Count of dispatched messages 855 */ dispatchCount()856 u_int64_t dispatchCount() const 857 { return m_dispatchCount; } 858 859 /** 860 * Get the queued messages high watermark 861 * @return Highest number of messages in queue 862 */ queuedMax()863 u_int64_t queuedMax() const 864 { return m_queuedMax; } 865 866 /** 867 * Get the average dequeued message age in milliseconds or microseconds 868 * @param usec True to return microseconds instead of milliseconds 869 * @return Average age of dequeued messages 870 */ 871 u_int64_t messageAge(bool usec = false) const 872 { return usec ? m_msgAvgAge : ((m_msgAvgAge + 500) / 1000); } 873 874 /** 875 * Retrieve all statistics counters 876 * @param enqueued Returns count of enqueued messages 877 * @param dequeued Returns count of dequeued messages 878 * @param dispatched Returns count of all dispatched messages, including dequeued ones 879 * @param queueMax Returns queued high watermark 880 */ 881 void getStats(u_int64_t& enqueued, u_int64_t& dequeued, u_int64_t& dispatched, u_int64_t& queueMax); 882 883 /** 884 * Install or remove a hook to catch messages after being dispatched 885 * @param hook Pointer to a post-dispatching message hook 886 * @param remove Set to True to remove the hook instead of adding 887 */ 888 void setHook(MessagePostHook* hook, bool remove = false); 889 890 protected: 891 /** 892 * Set the tracked parameter name 893 * @param paramName Name of the parameter used in tracking handlers 894 */ trackParam(const char * paramName)895 inline void trackParam(const char* paramName) 896 { m_trackParam = paramName; } 897 898 private: 899 ObjList m_handlers; 900 ObjList m_messages; 901 ObjList m_hooks; 902 Mutex m_hookMutex; 903 ObjList* m_msgAppend; 904 ObjList* m_hookAppend; 905 String m_trackParam; 906 unsigned int m_changes; 907 u_int64_t m_warnTime; 908 u_int64_t m_enqueueCount; 909 u_int64_t m_dequeueCount; 910 u_int64_t m_dispatchCount; 911 u_int64_t m_queuedMax; 912 u_int64_t m_msgAvgAge; 913 int m_hookCount; 914 bool m_hookHole; 915 }; 916 917 /** 918 * Abstract class for message hook 919 * @short Abstract message hook 920 */ 921 class YATE_API MessageHook : public RefObject 922 { 923 public: 924 /** 925 * Try to enqueue a message to this hook's queue 926 * @param msg The message to enqueue 927 * @return True if the message was enqueued. 928 */ 929 virtual bool enqueue(Message* msg) = 0; 930 931 /** 932 * Clear this hook data 933 */ 934 virtual void clear() = 0; 935 936 /** 937 * Check if the given message can be inserted in this queue 938 * @param msg The message to check 939 * @return True if the message can be inserted in this queue 940 */ 941 virtual bool matchesFilter(const Message& msg) = 0; 942 }; 943 944 945 /** 946 * MessageQueue class allows to create a private queue for a message who matches 947 * the specified filters. 948 * @short A message queue 949 */ 950 class YATE_API MessageQueue : public MessageHook, public Mutex 951 { 952 friend class Engine; 953 public: 954 /** 955 * Creates a new message queue. 956 * @param hookName Name of the message served by this queue 957 * @param numWorkers The number of workers who serve this queue 958 */ 959 MessageQueue(const char* hookName, int numWorkers = 0); 960 961 /** 962 * Destroys the message queue 963 */ 964 ~MessageQueue(); 965 966 /** 967 * Append a message in the queue 968 * @param msg The message to enqueue, will be destroyed after the processing is done 969 * @return True if successfully queued, false otherwise 970 */ 971 virtual bool enqueue(Message* msg); 972 973 /** 974 * Process a message from the waiting queue 975 * @return False if the message queue is empty 976 */ 977 bool dequeue(); 978 979 /** 980 * Add a new filter to this queue 981 * @param name The filter name 982 * @param value The filter value 983 */ 984 void addFilter(const char* name, const char* value); 985 986 /** 987 * Remove a filter form this queue 988 * @param name The filter name 989 */ 990 void removeFilter(const String& name); 991 992 /** 993 * Clear private data 994 */ 995 virtual void clear(); 996 997 /** 998 * Remove a thread from workers list 999 * @param thread The thread to remove 1000 */ 1001 void removeThread(Thread* thread); 1002 1003 /** 1004 * Helper method to obtain the number of unprocessed messages in the queue 1005 * @return The number of queued messages. 1006 */ count()1007 inline unsigned int count() const 1008 { return m_count; } 1009 1010 /** 1011 * Obtain the filter list for this queue 1012 * @return The filter list 1013 */ getFilters()1014 inline const NamedList& getFilters() const 1015 { return m_filters; } 1016 1017 /** 1018 * Check if the given message can be inserted in this queue 1019 * @param msg The message to check 1020 * @return True if the message can be inserted in this queue 1021 */ 1022 virtual bool matchesFilter(const Message& msg); 1023 protected: 1024 1025 /** 1026 * Callback method for message processing 1027 * Default calls Engine::dispatch 1028 * @param msg The message to process 1029 */ 1030 virtual void received(Message& msg); 1031 1032 private: 1033 NamedList m_filters; 1034 ObjList m_messages; 1035 ObjList m_workers; 1036 ObjList* m_append; 1037 unsigned int m_count; 1038 }; 1039 1040 1041 /** 1042 * Initialization and information about plugins. 1043 * Plugins are located in @em shared libraries that are loaded at runtime. 1044 * 1045 *<pre> 1046 * // Create static Plugin object by using the provided macro 1047 * INIT_PLUGIN(Plugin); 1048 *</pre> 1049 * @short Plugin support 1050 */ 1051 class YATE_API Plugin : public GenObject, public DebugEnabler 1052 { 1053 public: 1054 /** 1055 * Creates a new Plugin container. 1056 * @param name the undecorated name of the library that contains the plugin 1057 * @param earlyInit True to initialize the plugin early 1058 */ 1059 explicit Plugin(const char* name, bool earlyInit = false); 1060 1061 /** 1062 * Destroys the plugin. 1063 * The destructor must never be called directly - the Loader will do it 1064 * when the shared object's reference count reaches zero. 1065 */ 1066 virtual ~Plugin(); 1067 1068 /** 1069 * Get a string representation of this object 1070 * @return Name of the plugin 1071 */ toString()1072 virtual const String& toString() const 1073 { return m_name; } 1074 1075 /** 1076 * Get a pointer to a derived class given that class name 1077 * @param name Name of the class we are asking for 1078 * @return Pointer to the requested class or NULL if this object doesn't implement it 1079 */ 1080 virtual void* getObject(const String& name) const; 1081 1082 /** 1083 * Initialize the plugin after it was loaded and registered. 1084 */ 1085 virtual void initialize() = 0; 1086 1087 /** 1088 * Check if the module is actively used. 1089 * @return True if the plugin is in use, false if should be ok to restart 1090 */ isBusy()1091 virtual bool isBusy() const 1092 { return false; } 1093 1094 /** 1095 * Retrieve the name of the plugin 1096 * @return The plugin's name as String 1097 */ name()1098 inline const String& name() const 1099 { return m_name; } 1100 1101 /** 1102 * Retrive the objects counter associated to this plugin 1103 * @return Pointer to plugin's objects counter or NULL 1104 */ objectsCounter()1105 inline NamedCounter* objectsCounter() const 1106 { return m_counter; } 1107 1108 /** 1109 * Check if the module is to be initialized early 1110 * @return True if the module should be initialized before regular ones 1111 */ earlyInit()1112 bool earlyInit() const 1113 { return m_early; } 1114 1115 private: 1116 Plugin(); // no default constructor please 1117 String m_name; 1118 NamedCounter* m_counter; 1119 bool m_early; 1120 }; 1121 1122 #if 0 /* for documentation generator */ 1123 /** 1124 * Macro to create static instance of the plugin 1125 * @param pclass Class of the plugin to create 1126 */ 1127 void INIT_PLUGIN(class pclass); 1128 1129 /** 1130 * Macro to create the unloading function 1131 * @param unloadNow True if asked to unload immediately, false if just checking 1132 * @return True if the plugin can be unloaded, false if not 1133 */ 1134 bool UNLOAD_PLUGIN(bool unloadNow); 1135 #endif 1136 1137 #define INIT_PLUGIN(pclass) static pclass __plugin 1138 #ifdef DISABLE_UNLOAD 1139 #define UNLOAD_PLUGIN(arg) static bool _unused_unload(bool arg) 1140 #else 1141 #ifdef _WINDOWS 1142 #define UNLOAD_PLUGIN(arg) extern "C" __declspec(dllexport) bool _unload(bool arg) 1143 #else 1144 #define UNLOAD_PLUGIN(arg) extern "C" bool _unload(bool arg) 1145 #endif 1146 #endif 1147 1148 /** 1149 * Base class for engine running stage checkers. 1150 * Descendants may check specific conditions and decide to stop the engine. 1151 * There should be only one (static) instance of an engine checker 1152 * @short Engine checker interface 1153 */ 1154 class YATE_API EngineCheck 1155 { 1156 public: 1157 /** 1158 * Do-nothing destructor of base class 1159 */ ~EngineCheck()1160 virtual ~EngineCheck() 1161 { } 1162 1163 /** 1164 * Check running conditions. This method is called by the engine in the initialize process 1165 * @param cmds Optional list of strings containing extra command line parameters 1166 * (not parsed by the engine) 1167 * @return False to stop the program 1168 */ 1169 virtual bool check(const ObjList* cmds) = 0; 1170 1171 /** 1172 * Set the current engine checker 1173 * @param ptr The new engine checker. May be 0 to reset it 1174 */ 1175 static void setChecker(EngineCheck* ptr = 0); 1176 }; 1177 1178 /** 1179 * Prototype for engine main loop callback 1180 */ 1181 typedef int (*EngineLoop)(); 1182 1183 /** 1184 * This class holds global information about the engine. 1185 * Note: this is a singleton class. 1186 * 1187 * @short Engine globals 1188 */ 1189 class YATE_API Engine 1190 { 1191 friend class EnginePrivate; 1192 friend class EngineCommand; 1193 YNOCOPY(Engine); // no automatic copies please 1194 public: 1195 /** 1196 * Running modes - run the engine as Console, Client or Server. 1197 */ 1198 enum RunMode { 1199 Stopped = 0, 1200 Console = 1, 1201 Server = 2, 1202 Client = 3, 1203 ClientProxy = 4, 1204 }; 1205 1206 enum CallAccept { 1207 Accept = 0, 1208 Partial = 1, 1209 Congestion = 2, 1210 Reject = 3, 1211 }; 1212 1213 /** 1214 * Plugin load and initialization modes. 1215 * Default is LoadLate that initailizes the plugin after others. 1216 * LoadEarly will move the plugin to the front of the init order. 1217 * LoadFail causes the plugin to be unloaded. 1218 */ 1219 enum PluginMode { 1220 LoadFail = 0, 1221 LoadLate, 1222 LoadEarly 1223 }; 1224 1225 /** 1226 * Main entry point to be called directly from a wrapper program 1227 * @param argc Argument count 1228 * @param argv Argument array 1229 * @param env Environment variables 1230 * @param mode Mode the engine must run as - Console, Client or Server 1231 * @param loop Callback function to the main thread's loop 1232 * @param fail Fail and return after parsing command line arguments 1233 * @return Program exit code 1234 */ 1235 static int main(int argc, const char** argv, const char** env, 1236 RunMode mode = Console, EngineLoop loop = 0, bool fail = false); 1237 1238 /** 1239 * Display the help information on console 1240 * @param client Display help for client running mode 1241 * @param errout Display on stderr intead of stdout 1242 */ 1243 static void help(bool client, bool errout = false); 1244 1245 /** 1246 * Initialize the engine 1247 * @return Error code, 0 for success 1248 */ 1249 int engineInit(); 1250 1251 /** 1252 * Do engine cleanup 1253 * @return Error code, 0 for success 1254 */ 1255 int engineCleanup(); 1256 1257 /** 1258 * Run the engine. 1259 * @return Error code, 0 for success 1260 */ 1261 int run(); 1262 1263 /** 1264 * Get a pointer to the unique instance. 1265 * @return A pointer to the singleton instance of the engine 1266 */ 1267 static Engine* self(); 1268 1269 /** 1270 * Get the running mode of the engine 1271 * @return Engine's run mode as enumerated value 1272 */ mode()1273 static RunMode mode() 1274 { return s_mode; } 1275 1276 /** 1277 * Get call accept status 1278 * @return Engine's call accept status as enumerated value 1279 */ accept()1280 inline static CallAccept accept() { 1281 return (s_congestion && (s_accept < Congestion)) ? Congestion : s_accept; 1282 } 1283 1284 /** 1285 * Set call accept status 1286 * @param ca New call accept status as enumerated value 1287 */ setAccept(CallAccept ca)1288 inline static void setAccept(CallAccept ca) { 1289 s_accept = ca; 1290 } 1291 1292 /** 1293 * Get call accept states 1294 * @return states Pointer to the call accept states TokenDict 1295 */ getCallAcceptStates()1296 inline static const TokenDict* getCallAcceptStates() { 1297 return s_callAccept; 1298 } 1299 1300 /** 1301 * Alter the congestion state counter. 1302 * @param reason Reason to enter congested state, NULL to leave congestion 1303 */ 1304 static void setCongestion(const char* reason = 0); 1305 1306 /** 1307 * Get the congestion state counter 1308 * @return Zero if not congested else the number of congested components 1309 */ getCongestion()1310 static unsigned int getCongestion() 1311 { return s_congestion; } 1312 1313 /** 1314 * Check if the engine is running as telephony client 1315 * @return True if the engine is running in client mode 1316 */ clientMode()1317 inline static bool clientMode() 1318 { return (s_mode == Client) || (s_mode == ClientProxy); } 1319 1320 /** 1321 * Register or unregister a plugin to the engine. 1322 * @param plugin A pointer to the plugin to (un)register 1323 * @param reg True to register (default), false to unregister 1324 * @return True on success, false on failure 1325 */ 1326 static bool Register(const Plugin* plugin, bool reg = true); 1327 1328 /** 1329 * Get the server node name, should be unique in a cluster 1330 * @return Node identifier string, defaults to host name 1331 */ nodeName()1332 inline static const String& nodeName() 1333 { return s_node; } 1334 1335 /** 1336 * Get the application's shared directory path 1337 * @return The base path for shared files and directories 1338 */ sharedPath()1339 inline static const String& sharedPath() 1340 { return s_shrpath; } 1341 1342 /** 1343 * Get the filename for a specific configuration 1344 * @param name Name of the configuration requested 1345 * @param user True to build a user settings path 1346 * @return A full path configuration file name 1347 */ 1348 static String configFile(const char* name, bool user = false); 1349 1350 /** 1351 * Get the system or user configuration directory path 1352 * @param user True to get the user settings path 1353 * @return The directory path for system or user configuration files 1354 */ 1355 static const String& configPath(bool user = false); 1356 1357 /** 1358 * Get the configuration file suffix 1359 * @return The suffix for configuration files 1360 */ configSuffix()1361 inline static const String& configSuffix() 1362 { return s_cfgsuffix; } 1363 1364 /** 1365 * The module loading path 1366 */ modulePath()1367 inline static const String& modulePath() 1368 { return s_modpath; } 1369 1370 /** 1371 * Add a relative extra module loading path. The list is empty by default 1372 * but can be filled by a main program before calling @ref main() 1373 * @param path Relative path to extra modules to be loaded 1374 */ 1375 static void extraPath(const String& path); 1376 1377 /** 1378 * Set the per user application data path. This method must be called 1379 * by a main program before calling @ref main() or @ref help() 1380 * Path separators are not allowed. The default is taken from CFG_DIR. 1381 * @param path Single relative path component to write user specific data 1382 */ 1383 static void userPath(const String& path); 1384 1385 /** 1386 * Get the module filename suffix 1387 * @return The suffix for module files 1388 */ moduleSuffix()1389 inline static const String& moduleSuffix() 1390 { return s_modsuffix; } 1391 1392 /** 1393 * Get the canonical path element separator for the operating system 1394 * @return The operating system specific path element separator 1395 */ 1396 static const char* pathSeparator(); 1397 1398 /** 1399 * The global configuration of the engine. 1400 * You must use this resource with caution. 1401 * Note that sections [general], [modules], [preload] and [postload] are 1402 * reserved by the engine. Also [telephony] is reserved by the drivers. 1403 * @return A reference to the read-only engine configuration 1404 */ 1405 static const Configuration& config(); 1406 1407 /** 1408 * Get a - supposedly unique - instance ID 1409 * @return Unique ID of the current running instance 1410 */ 1411 static unsigned int runId(); 1412 1413 /** 1414 * Get the engine parameters specific to this run. 1415 * @return A reference to the list of run specific parameters 1416 */ runParams()1417 inline static const NamedList& runParams() 1418 { return s_params; } 1419 1420 /** 1421 * Reinitialize the plugins 1422 */ 1423 static void init(); 1424 1425 /** 1426 * Reinitialize one plugin 1427 * @param name Name of the plugin to initialize, emplty, "*" or "all" to initialize all 1428 * @return True if plugin(s) were reinitialized 1429 */ 1430 static bool init(const String& name); 1431 1432 /** 1433 * Stop the engine and the entire program 1434 * @param code Return code of the program 1435 */ 1436 static void halt(unsigned int code); 1437 1438 /** 1439 * Stop and restart the engine and the entire program 1440 * @param code Return code of the program 1441 * @param gracefull Attempt to wait until no plugin is busy 1442 * @return True if restart was initiated, false if exiting or no supervisor 1443 */ 1444 static bool restart(unsigned int code, bool gracefull = false); 1445 1446 /** 1447 * Check if the engine was started 1448 * @return True if the engine has gone through the start phase 1449 */ started()1450 static bool started() 1451 { return s_started; } 1452 1453 /** 1454 * Check if the engine is currently exiting 1455 * @return True if exiting, false in normal operation 1456 */ exiting()1457 static bool exiting() 1458 { return (s_haltcode != -1); } 1459 1460 /** 1461 * Installs a handler in the dispatcher. 1462 * @param handler A pointer to the handler to install 1463 * @return True on success, false on failure 1464 */ 1465 static bool install(MessageHandler* handler); 1466 1467 /** 1468 * Uninstalls a handler drom the dispatcher. 1469 * @param handler A pointer to the handler to uninstall 1470 * @return True on success, false on failure 1471 */ 1472 static bool uninstall(MessageHandler* handler); 1473 1474 /** 1475 * Enqueue a message in the message queue for asynchronous dispatching 1476 * @param msg The message to enqueue, will be destroyed after dispatching 1477 * @param skipHooks True to append the message directly into the main queue 1478 * @return True if enqueued, false on error (already queued) 1479 */ 1480 static bool enqueue(Message* msg, bool skipHooks = false); 1481 1482 /** 1483 * Convenience function. 1484 * Enqueue a new parameterless message in the message queue 1485 * @param name Name of the parameterless message to put in queue 1486 * @param broadcast Broadcast flag, true if handling the mesage must not stop it 1487 * @return True if enqueued, false on error (already queued) 1488 */ 1489 inline static bool enqueue(const char* name, bool broadcast = false) 1490 { return name && *name && enqueue(new Message(name,0,broadcast)); } 1491 1492 /** 1493 * Synchronously dispatch a message to the registered handlers 1494 * @param msg Pointer to the message to dispatch 1495 * @return True if one handler accepted it, false if all ignored 1496 */ 1497 static bool dispatch(Message* msg); 1498 1499 /** 1500 * Synchronously dispatch a message to the registered handlers 1501 * @param msg The message to dispatch 1502 * @return True if one handler accepted it, false if all ignored 1503 */ 1504 static bool dispatch(Message& msg); 1505 1506 /** 1507 * Convenience function. 1508 * Dispatch a parameterless message to the registered handlers 1509 * @param name The name of the message to create and dispatch 1510 * @param broadcast Broadcast flag, true if handling the mesage must not stop it 1511 * @return True if one handler accepted it, false if all ignored 1512 */ 1513 static bool dispatch(const char* name, bool broadcast = false); 1514 1515 /** 1516 * Install or remove a hook to catch messages after being dispatched 1517 * @param hook Pointer to a post-dispatching message hook 1518 * @param remove Set to True to remove the hook instead of adding 1519 */ 1520 inline void setHook(MessagePostHook* hook, bool remove = false) 1521 { m_dispatcher.setHook(hook,remove); } 1522 1523 /** 1524 * Retrieve the tracker parameter name 1525 * @return Name of the parameter used to track message dispatching 1526 */ trackParam()1527 inline static const String& trackParam() 1528 { return s_self ? s_self->m_dispatcher.trackParam() : String::empty(); } 1529 1530 /** 1531 * Appends a new message hook to the hooks list. 1532 * @param hook The message hook to append. 1533 * @return True if the message hook was successfully appended to the hooks list 1534 */ 1535 static bool installHook(MessageHook* hook); 1536 1537 /** 1538 * Remove a message hook from the hooks list. 1539 * @param hook The hook to remove. 1540 */ 1541 static void uninstallHook(MessageHook* hook); 1542 1543 /** 1544 * Get a count of plugins that are actively in use 1545 * @return Count of plugins in use 1546 */ 1547 int usedPlugins(); 1548 1549 /** 1550 * Get the number of messages waiting in the queue 1551 * @return Count of messages in the queue 1552 */ messageCount()1553 inline unsigned int messageCount() 1554 { return m_dispatcher.messageCount(); } 1555 1556 /** 1557 * Get the number of handlers in the dispatcher 1558 * @return Count of handlers 1559 */ handlerCount()1560 inline unsigned int handlerCount() 1561 { return m_dispatcher.handlerCount(); } 1562 1563 /** 1564 * Get the number of post-handling hooks in the dispatcher 1565 * @return Count of hooks 1566 */ postHookCount()1567 inline unsigned int postHookCount() 1568 { return m_dispatcher.postHookCount(); } 1569 1570 /** 1571 * Get the rate of dispatched messages per second 1572 * @return Number of messages dispatched in the last second 1573 */ messageRate()1574 inline unsigned int messageRate() const 1575 { return m_messageRate; } 1576 1577 /** 1578 * Get the maximum rate of dispatched messages per second 1579 * @return Maximum number of messages dispatched per second 1580 */ messageMaxRate()1581 inline unsigned int messageMaxRate() const 1582 { return m_maxMsgRate; } 1583 1584 /** 1585 * Get the average dequeued message age in milliseconds or microseconds 1586 * @param usec True to return microseconds instead of milliseconds 1587 * @return Average age of dequeued messages 1588 */ 1589 unsigned int messageAge(bool usec = false) const 1590 { return (unsigned int)m_dispatcher.messageAge(usec); } 1591 1592 /** 1593 * Retrieve dispatcher's statistics counters 1594 * @param enqueued Returns count of enqueued messages 1595 * @param dequeued Returns count of dequeued messages 1596 * @param dispatched Returns count of all dispatched messages, including dequeued ones 1597 * @param queueMax Returns queued high watermark 1598 */ getStats(u_int64_t & enqueued,u_int64_t & dequeued,u_int64_t & dispatched,u_int64_t & queueMax)1599 inline void getStats(u_int64_t& enqueued, u_int64_t& dequeued, u_int64_t& dispatched, u_int64_t& queueMax) 1600 { m_dispatcher.getStats(enqueued,dequeued,dispatched,queueMax); } 1601 1602 /** 1603 * Reset the high water mark of the stat counters 1604 */ resetMax()1605 inline void resetMax() 1606 { m_maxMsgRate = m_messageRate; m_dispatcher.m_queuedMax = m_dispatcher.messageCount(); } 1607 1608 /** 1609 * Check if a plugin is currently loaded 1610 * @param name Name of the plugin to check 1611 * @return True if the named plugin is loaded 1612 */ pluginLoaded(const String & name)1613 inline bool pluginLoaded(const String& name) const 1614 { return !!m_libs[name]; } 1615 1616 /** 1617 * Loads the plugins from an extra plugins directory or just an extra plugin 1618 * @param relPath Path to the extra directory, relative to the main modules 1619 * @return True if the plugin was loaded or the directory could at least be opened 1620 */ 1621 bool loadPluginDir(const String& relPath); 1622 1623 /** 1624 * Set the load and init mode of the currently loading @ref Plugin 1625 * @param mode Load and init mode, default LoadLate 1626 */ 1627 static void pluginMode(PluginMode mode); 1628 1629 /** 1630 * Retrive the list of captured events of a specific type 1631 * @param type Type of captured events, an empty name returns engine events 1632 * @return List containing captured events of specified type, NULL if not found 1633 */ 1634 static const ObjList* events(const String& type); 1635 1636 /** 1637 * Clear the list of captured events of a specific type 1638 * @param type Type of captured events, an empty name clear engine events 1639 */ 1640 static void clearEvents(const String& type); 1641 1642 /** 1643 * Access the engine's shared variables 1644 * @return Reference to the static variables shared between modules 1645 */ 1646 static SharedVars& sharedVars(); 1647 1648 /** 1649 * Append command line arguments form current config. 1650 * The following parameters are added: -Dads, -v, -q, Debugger timestamp. 1651 * This method should be used when starting another libyate based application 1652 * @param line Destination string 1653 */ 1654 static void buildCmdLine(String& line); 1655 1656 /** 1657 * Initialize library from command line arguments. 1658 * Enable debugger output. 1659 * This method should be used in initialization stage of libyate based applications 1660 * @param line Command line arguments string 1661 * @param output Optional string to be filled with invalid argument errors 1662 * or any output to be displyed later 1663 */ 1664 static void initLibrary(const String& line, String* output = 0); 1665 1666 /** 1667 * Cleanup library. Set late abort, kill all threads. 1668 * This method should be used in cleanup stage of libyate based applications 1669 * @return Halt code 1670 */ 1671 static int cleanupLibrary(); 1672 1673 protected: 1674 /** 1675 * Destroys the engine and everything. You must not call it directly, 1676 * @ref run() will do it for you. 1677 */ 1678 ~Engine(); 1679 1680 /** 1681 * Loads one plugin from a shared object file 1682 * @param file Name of the plugin file to load 1683 * @param local Attempt to keep symbols local if supported by the system 1684 * @param nounload Never unload the module from memory, finalize if possible 1685 * @return True if success, false on failure 1686 */ 1687 bool loadPlugin(const char* file, bool local = false, bool nounload = false); 1688 1689 /** 1690 * Loads the plugins from the plugins directory 1691 */ 1692 void loadPlugins(); 1693 1694 /** 1695 * Initialize all registered plugins 1696 */ 1697 void initPlugins(); 1698 1699 private: 1700 Engine(); 1701 void internalStatisticsStart(); 1702 void tryPluginFile(const String& name, const String& path, bool defload); 1703 ObjList m_libs; 1704 MessageDispatcher m_dispatcher; 1705 uint64_t m_dispatchedLast; 1706 unsigned int m_messageRate; 1707 unsigned int m_maxMsgRate; 1708 bool m_rateCongested; 1709 bool m_queueCongested; 1710 bool m_ageCongested; 1711 static Engine* s_self; 1712 static String s_node; 1713 static String s_shrpath; 1714 static String s_cfgsuffix; 1715 static String s_modpath; 1716 static String s_modsuffix; 1717 static ObjList s_extramod; 1718 static NamedList s_params; 1719 static int s_haltcode; 1720 static RunMode s_mode; 1721 static bool s_started; 1722 static unsigned int s_congestion; 1723 static CallAccept s_accept; 1724 static const TokenDict s_callAccept[]; 1725 }; 1726 1727 }; // namespace TelEngine 1728 1729 #endif /* __YATENGINE_H */ 1730 1731 /* vi: set ts=8 sw=4 sts=4 noet: */ 1732