1 /** 2 * yatephone.h 3 * This file is part of the YATE Project http://YATE.null.ro 4 * 5 * Drivers, channels and telephony 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 __YATEPHONE_H 23 #define __YATEPHONE_H 24 25 #ifndef __cplusplus 26 #error C++ is required 27 #endif 28 29 #include <yatengine.h> 30 31 /** 32 * Holds all Telephony Engine related classes. 33 */ 34 namespace TelEngine { 35 36 /** 37 * A structure to hold information about a static picture or video frame. 38 */ 39 struct YATE_API ImageInfo { 40 /** 41 * Width of the image in pixels 42 */ 43 int width; 44 45 /** 46 * Height of the image in pixels 47 */ 48 int height; 49 50 /** 51 * Bit depth of the image, 0 for unknown/irrelevant 52 */ 53 int depth; 54 }; 55 56 /** 57 * A structure to hold information about a data format. 58 */ 59 struct YATE_API FormatInfo { 60 /** 61 * Standard no-blanks lowercase format name 62 */ 63 const char* name; 64 65 /** 66 * Format type: "audio", "video", "text" 67 */ 68 const char* type; 69 70 /** 71 * Frame size in octets/frame, 0 for non-framed formats 72 */ 73 int frameSize; 74 75 /** 76 * Frame time in microseconds, 0 for variable 77 */ 78 int frameTime; 79 80 /** 81 * Rate in samples/second (audio) or 1e-6 frames/second (video), 0 for unknown 82 */ 83 int sampleRate; 84 85 /** 86 * Number of channels, typically 1 87 */ 88 int numChannels; 89 90 /** 91 * If this is a valid candidate for conversion 92 */ 93 bool converter; 94 95 /** 96 * Guess the number of samples in an encoded data block 97 * @param len Length of the data block in octets 98 * @return Number of samples or 0 if unknown 99 */ 100 int guessSamples(int len) const; 101 102 /** 103 * Get the data rate in bytes/s 104 * @return Data rate or 0 if variable/undefined 105 */ 106 int dataRate() const; 107 108 /** 109 * Default constructor - used to initialize arrays 110 */ FormatInfoFormatInfo111 inline FormatInfo() 112 : name(0), type("audio"), 113 frameSize(0), frameTime(0), 114 sampleRate(8000), numChannels(1), 115 converter(false) 116 { } 117 118 /** 119 * Normal constructor 120 */ 121 inline explicit FormatInfo(const char* _name, int fsize = 0, int ftime = 10000, 122 const char* _type = "audio", int srate = 8000, int nchan = 1, bool convert = false) nameFormatInfo123 : name(_name), type(_type), 124 frameSize(fsize), frameTime(ftime), 125 sampleRate(srate), numChannels(nchan), 126 converter(convert) 127 { } 128 }; 129 130 class DataEndpoint; 131 class CallEndpoint; 132 class Driver; 133 134 /** 135 * A structure to build (mainly static) translator capability tables. 136 * A table of such structures must end with an entry with null format names. 137 */ 138 struct YATE_API TranslatorCaps { 139 /** Description of source (input) data format */ 140 const FormatInfo* src; 141 /** Description of destination (output) data format */ 142 const FormatInfo* dest; 143 /** Computing cost in KIPS of converting a stream from src to dest */ 144 int cost; 145 }; 146 147 /** 148 * This is just a holder for the list of media formats supported by Yate 149 * @short A repository for media formats 150 */ 151 class YATE_API FormatRepository 152 { 153 YNOCOPY(FormatRepository); // no automatic copies please 154 private: 155 FormatRepository(); 156 public: 157 /** 158 * Retrieve a format by name and type 159 * @param name Standard name of the format to find 160 * @return Pointer to the format info or NULL if not found 161 */ 162 static const FormatInfo* getFormat(const String& name); 163 164 /** 165 * Add a new format to the repository 166 * @param name Standard no-blanks lowercase format name 167 * @param fsize Data frame size in octets/frame, 0 for non-framed formats 168 * @param ftime Data frame duration in microseconds, 0 for variable 169 * @param type Format type: "audio", "video", "text" 170 * @param srate Rate in samples/second (audio) or 1e-6 frames/second (video), 0 for unknown 171 * @param nchan Number of channels, typically 1 172 * @return Pointer to the format info or NULL if another incompatible 173 * format with the same name was already registered 174 */ 175 static const FormatInfo* addFormat(const String& name, int fsize, int ftime, const String& type = "audio", int srate = 8000, int nchan = 1); 176 }; 177 178 /** 179 * An extension of a String that can parse data formats 180 * @short A Data format 181 */ 182 class YATE_API DataFormat : public NamedList 183 { 184 public: 185 /** 186 * Creates a new, empty format string. 187 */ DataFormat()188 inline DataFormat() 189 : NamedList((const char*)0), m_parsed(0) 190 { } 191 192 /** 193 * Creates a new initialized format. 194 * @param value Initial value of the format 195 */ DataFormat(const char * value)196 inline DataFormat(const char* value) 197 : NamedList(value), m_parsed(0) 198 { } 199 200 /** 201 * Copy constructor. 202 * @param value Initial value of the format 203 */ DataFormat(const DataFormat & value)204 inline DataFormat(const DataFormat& value) 205 : NamedList(value), m_parsed(value.getInfo()) 206 { } 207 208 /** 209 * Constructor from String reference 210 * @param value Initial value of the format 211 */ DataFormat(const String & value)212 inline DataFormat(const String& value) 213 : NamedList(value), m_parsed(0) 214 { } 215 216 /** 217 * Constructor from NamedList reference 218 * @param value Initial value of the format and parameters 219 */ DataFormat(const NamedList & value)220 inline DataFormat(const NamedList& value) 221 : NamedList(value), m_parsed(0) 222 { } 223 224 /** 225 * Constructor from String pointer. 226 * @param value Initial value of the format 227 */ DataFormat(const String * value)228 inline DataFormat(const String* value) 229 : NamedList(value ? value->c_str() : (const char*)0), m_parsed(0) 230 { } 231 232 /** 233 * Constructor from format information 234 * @param format Pointer to existing FormatInfo 235 */ DataFormat(const FormatInfo * format)236 inline explicit DataFormat(const FormatInfo* format) 237 : NamedList(format ? format->name : (const char*)0), m_parsed(format) 238 { } 239 240 /** 241 * Assignment operator. 242 */ 243 inline DataFormat& operator=(const DataFormat& value) 244 { NamedList::operator=(value); m_parsed = value.getInfo(); return *this; } 245 246 /** 247 * Retrieve a pointer to the format information 248 * @return Pointer to the associated format info or NULL if error 249 */ 250 const FormatInfo* getInfo() const; 251 252 /** 253 * Retrieve the frame size 254 * @param defValue Default value to return if format is unknown 255 * @return Frame size in octets/frame, 0 for non-framed, defValue if unknown 256 */ 257 inline int frameSize(int defValue = 0) const 258 { return getInfo() ? getInfo()->frameSize : defValue; } 259 260 /** 261 * Retrieve the frame time 262 * @param defValue Default value to return if format is unknown 263 * @return Frame time in microseconds, 0 for variable, defValue if unknown 264 */ 265 inline int frameTime(int defValue = 0) const 266 { return getInfo() ? getInfo()->frameTime : defValue; } 267 268 /** 269 * Retrieve the sample rate 270 * @param defValue Default value to return if format is unknown 271 * @return Rate in samples/second (audio) or 1e-6 frames/second (video), 272 * 0 for unknown, defValue if unknown format 273 */ 274 inline int sampleRate(int defValue = 0) const 275 { return getInfo() ? getInfo()->sampleRate : defValue; } 276 277 /** 278 * Retrieve the number of channels 279 * @param defValue Default value to return if format is unknown 280 * @return Number of channels (typically 1), defValue if unknown format 281 */ 282 inline int numChannels(int defValue = 1) const 283 { return getInfo() ? getInfo()->numChannels : defValue; } 284 285 protected: 286 /** 287 * Called whenever the value changed (except in constructors). 288 */ 289 virtual void changed(); 290 291 private: 292 mutable const FormatInfo* m_parsed; 293 }; 294 295 /** 296 * A generic data handling object 297 */ 298 class YATE_API DataNode : public RefObject 299 { 300 friend class DataEndpoint; 301 YNOCOPY(DataNode); // no automatic copies please 302 public: 303 /** 304 * Flags associated with the DataBlocks forwarded between nodes 305 */ 306 enum DataFlags { 307 DataStart = 0x0001, 308 DataEnd = 0x0002, 309 DataMark = 0x0004, 310 DataSilent = 0x0008, 311 DataMissed = 0x0010, 312 DataError = 0x0020, 313 DataPrivate = 0x0100 314 }; 315 316 /** 317 * Construct a DataNode 318 * @param format Description of the data format, default none 319 */ 320 inline explicit DataNode(const char* format = 0) m_format(format)321 : m_format(format), m_timestamp(0) 322 { } 323 324 /** 325 * Get the computing cost of converting the data to the format asked 326 * @param format Name of the format to check for 327 * @return -1 if unsupported, 0 for native format else cost in KIPS 328 */ costFormat(const DataFormat & format)329 virtual int costFormat(const DataFormat& format) 330 { return -1; } 331 332 /** 333 * Change the format used to transfer data 334 * @param format Name of the format to set for data 335 * @return True if the format changed successfully, false if not changed 336 */ setFormat(const DataFormat & format)337 virtual bool setFormat(const DataFormat& format) 338 { return false; } 339 340 /** 341 * Get the description of the format currently in use 342 * @return Pointer to the data format 343 */ getFormat()344 inline const DataFormat& getFormat() const 345 { return m_format; } 346 347 /** 348 * Get the current position in the data stream 349 * @return Timestamp of current data position 350 */ timeStamp()351 inline unsigned long timeStamp() const 352 { return m_timestamp; } 353 354 /** 355 * Check if this data node is still valid 356 * @return True if still valid, false if node should be removed 357 */ valid()358 virtual bool valid() const 359 { return true; } 360 361 /** 362 * Modify node parameters 363 * @param params The list of parameters to change 364 * @return True if processed 365 */ control(NamedList & params)366 virtual bool control(NamedList& params) 367 { return false; } 368 369 /** 370 * Get the internal representation of an invalid or unknown timestamp 371 * @return Invalid timestamp - unsigned long conversion of -1 372 */ invalidStamp()373 inline static unsigned long invalidStamp() 374 { return (unsigned long)-1; } 375 376 /** 377 * Owner attach and detach notification. 378 * This method is called with @ref DataEndpoint::commonMutex() held 379 * @param added True if a new owner was added, false if it was removed 380 */ attached(bool added)381 virtual void attached(bool added) 382 { } 383 384 protected: 385 DataFormat m_format; 386 unsigned long m_timestamp; 387 }; 388 389 class DataSource; 390 class DataTranslator; 391 class TranslatorFactory; 392 class ThreadedSourcePrivate; 393 394 /** 395 * A data consumer 396 */ 397 class YATE_API DataConsumer : public DataNode 398 { 399 friend class DataSource; 400 401 public: 402 /** 403 * Consumer constructor 404 * @param format Name of the data format, default "slin" (Signed Linear) 405 */ 406 inline explicit DataConsumer(const char* format = "slin") DataNode(format)407 : DataNode(format), 408 m_source(0), m_override(0), 409 m_regularTsDelta(0), m_overrideTsDelta(0), m_lastTsTime(0) 410 { } 411 412 /** 413 * Destruct notification - complains loudly if still attached to a source 414 */ 415 virtual void destroyed(); 416 417 /** 418 * Get a pointer to a derived class given that class name 419 * @param name Name of the class we are asking for 420 * @return Pointer to the requested class or NULL if this object doesn't implement it 421 */ 422 virtual void* getObject(const String& name) const; 423 424 /** 425 * Consumes the data sent to it from a source 426 * @param data The raw data block to process 427 * @param tStamp Timestamp of data - typically samples 428 * @param flags Indicator flags associated with the data block 429 * @return Number of samples actually consumed, 430 * use invalidStamp() to indicate that all data was consumed, 431 * return zero for consumers that become invalid 432 */ 433 virtual unsigned long Consume(const DataBlock& data, unsigned long tStamp, unsigned long flags) = 0; 434 435 /** 436 * Get the data source of this object if it's connected 437 * @return A pointer to the DataSource object or NULL 438 */ getConnSource()439 inline DataSource* getConnSource() const 440 { return m_source; } 441 442 /** 443 * Get the override data source of this object if it's connected 444 * @return A pointer to the DataSource object or NULL 445 */ getOverSource()446 inline DataSource* getOverSource() const 447 { return m_override; } 448 449 /** 450 * Get the data source of a translator object 451 * @return A pointer to the DataSource object or NULL 452 */ getTransSource()453 virtual DataSource* getTransSource() const 454 { return 0; } 455 456 protected: 457 /** 458 * Synchronize the consumer with a source 459 * @param source Data source to copy the timestamp from 460 * @return True if we could synchronize with the source 461 */ 462 virtual bool synchronize(DataSource* source); 463 464 private: 465 unsigned long Consume(const DataBlock& data, unsigned long tStamp, 466 unsigned long flags, DataSource* source); 467 DataSource* m_source; 468 DataSource* m_override; 469 long m_regularTsDelta; 470 long m_overrideTsDelta; 471 u_int64_t m_lastTsTime; 472 }; 473 474 /** 475 * A data source 476 */ 477 class YATE_API DataSource : public DataNode, public Mutex 478 { 479 friend class DataTranslator; 480 YNOCOPY(DataSource); // no automatic copies please 481 public: 482 /** 483 * Source constructor 484 * @param format Name of the data format, default "slin" (Signed Linear) 485 */ 486 inline explicit DataSource(const char* format = "slin") DataNode(format)487 : DataNode(format), Mutex(false,"DataSource"), 488 m_nextStamp(invalidStamp()), m_translator(0) { } 489 490 /** 491 * Source's destruct notification - detaches all consumers 492 */ 493 virtual void destroyed(); 494 495 /** 496 * Get a pointer to a derived class given that class name 497 * @param name Name of the class we are asking for 498 * @return Pointer to the requested class or NULL if this object doesn't implement it 499 */ 500 virtual void* getObject(const String& name) const; 501 502 /** 503 * Check if this data source is still valid 504 * @return True if still valid, false if node should be removed 505 */ 506 virtual bool valid() const; 507 508 /** 509 * Modify source parameters, calls translator if one is set 510 * @param params The list of parameters to change 511 * @return True if processed 512 */ 513 virtual bool control(NamedList& params); 514 515 /** 516 * Forwards the data to its consumers 517 * @param data The raw data block to forward 518 * @param tStamp Timestamp of data - typically samples 519 * @param flags Indicator flags associated with the data block 520 * @return Number of samples actually forwarded to all consumers 521 */ 522 unsigned long Forward(const DataBlock& data, unsigned long tStamp = invalidStamp(), 523 unsigned long flags = 0); 524 525 /** 526 * Attach a data consumer 527 * @param consumer Data consumer to attach 528 * @param override Attach as temporary source override 529 * @return True on success, false on failure 530 */ 531 bool attach(DataConsumer* consumer, bool override = false); 532 533 /** 534 * Detach a data consumer 535 * @param consumer Data consumer to detach 536 * @return True on success, false on failure 537 */ 538 bool detach(DataConsumer* consumer); 539 540 /** 541 * Detach all data consumers 542 */ 543 void clear(); 544 545 /** 546 * Get the master translator object if this source is part of a translator 547 * @return A pointer to the DataTranslator object or NULL 548 */ getTranslator()549 inline DataTranslator* getTranslator() const 550 { return m_translator; } 551 552 /** 553 * Synchronize the source and attached consumers with another timestamp 554 * @param tStamp New timestamp of data - typically samples 555 */ 556 void synchronize(unsigned long tStamp); 557 558 /** 559 * Get the next expected position in the data stream 560 * @return Timestamp of next expected data position, may be invalid/unknown 561 */ nextStamp()562 inline unsigned long nextStamp() const 563 { return m_nextStamp; } 564 565 protected: 566 unsigned long m_nextStamp; 567 ObjList m_consumers; 568 private: setTranslator(DataTranslator * translator)569 inline void setTranslator(DataTranslator* translator) { 570 Lock mylock(this); 571 m_translator = translator; 572 } 573 bool detachInternal(DataConsumer* consumer); 574 DataTranslator* m_translator; 575 }; 576 577 /** 578 * A data source with a thread of its own 579 * @short Data source with own thread 580 */ 581 class YATE_API ThreadedSource : public DataSource 582 { 583 friend class ThreadedSourcePrivate; 584 public: 585 /** 586 * The destruction notification, checks that the thread is gone 587 */ 588 virtual void destroyed(); 589 590 /** 591 * Starts the worker thread 592 * @param name Static name of this thread 593 * @param prio Thread's priority 594 * @return True if started, false if an error occured 595 */ 596 bool start(const char* name = "ThreadedSource", Thread::Priority prio = Thread::Normal); 597 598 /** 599 * Stops and destroys the worker thread if running 600 */ 601 void stop(); 602 603 /** 604 * Return a pointer to the worker thread 605 * @return Pointer to running worker thread or NULL 606 */ 607 Thread* thread() const; 608 609 /** 610 * Check if the data thread is running 611 * @return True if the data thread was started and is running 612 */ 613 bool running() const; 614 615 protected: 616 /** 617 * Threaded Source constructor 618 * @param format Name of the data format, default "slin" (Signed Linear) 619 */ 620 inline explicit ThreadedSource(const char* format = "slin") DataSource(format)621 : DataSource(format), m_thread(0) 622 { } 623 624 /** 625 * The worker method. You have to reimplement it as you need 626 */ 627 virtual void run() = 0; 628 629 /** 630 * The cleanup after thread method, deletes the source if already 631 * dereferenced and set for asynchronous deletion 632 */ 633 virtual void cleanup(); 634 635 /** 636 * Check if the calling thread should keep looping the worker method 637 * @param runConsumers True to keep running as long consumers are attached 638 * @return True if the calling thread should remain in the run() method 639 */ 640 bool looping(bool runConsumers = false) const; 641 642 private: 643 ThreadedSourcePrivate* m_thread; 644 }; 645 646 /** 647 * The DataTranslator holds a translator (codec) capable of unidirectional 648 * conversion of data from one type to another. 649 * @short An unidirectional data translator (codec) 650 */ 651 class YATE_API DataTranslator : public DataConsumer 652 { 653 friend class TranslatorFactory; 654 public: 655 /** 656 * Construct a data translator. 657 * @param sFormat Name of the source format (data received from the consumer) 658 * @param dFormat Name of the destination format (data supplied to the source) 659 */ 660 DataTranslator(const char* sFormat, const char* dFormat); 661 662 /** 663 * Creates a data translator from an existing source, 664 * does not increment the source's reference counter. 665 * @param sFormat Name of the source format (data received from the consumer) 666 * @param source Optional pointer to a DataSource object 667 */ 668 explicit DataTranslator(const char* sFormat, DataSource* source = 0); 669 670 /** 671 * Destroys the translator and its source 672 */ 673 ~DataTranslator(); 674 675 /** 676 * Get a pointer to a derived class given that class name 677 * @param name Name of the class we are asking for 678 * @return Pointer to the requested class or NULL if this object doesn't implement it 679 */ 680 virtual void* getObject(const String& name) const; 681 682 /** 683 * Check if the data translator has a valid source 684 * @return True if still valid, false if node should be removed 685 */ valid()686 virtual bool valid() const 687 { return m_tsource && m_tsource->valid(); } 688 689 /** 690 * Get the data source of a translator object 691 * @return A pointer to the DataSource object or NULL 692 */ getTransSource()693 virtual DataSource* getTransSource() const 694 { return m_tsource; } 695 696 /** 697 * Get the first translator from a chain 698 * @return Pointer to the first translator in a chain 699 */ 700 DataTranslator* getFirstTranslator(); 701 702 /** 703 * Constant version to get the first translator from a chain 704 * @return Pointer to the first translator in a chain 705 */ 706 const DataTranslator* getFirstTranslator() const; 707 708 /** 709 * Get a list of formats supported for a given output format. 710 * @param dFormat Name of destination format 711 * @param maxCost Maximum cost of candidates to consider, -1 to accept all 712 * @param maxLen Maximum length of codec chains to consider, 0 to accept all 713 * @param lst Initial list, will append to it if not empty 714 * @return List of source format names, must be freed by the caller 715 */ 716 static ObjList* srcFormats(const DataFormat& dFormat = "slin", int maxCost = -1, unsigned int maxLen = 0, ObjList* lst = 0); 717 718 /** 719 * Get a list of formats supported for a given input format 720 * @param sFormat Name of source format 721 * @param maxCost Maximum cost of candidates to consider, -1 to accept all 722 * @param maxLen Maximum length of codec chains to consider, 0 to accept all 723 * @param lst Initial list, will append to it if not empty 724 * @return List of destination format names, must be freed by the caller 725 */ 726 static ObjList* destFormats(const DataFormat& sFormat = "slin", int maxCost = -1, unsigned int maxLen = 0, ObjList* lst = 0); 727 728 /** 729 * Get a list of formats supported by transcoding for a given format list 730 * @param formats List of data format names 731 * @param existing Also return formats already existing in the initial list 732 * @param sameRate Only return formats with same sampling rate 733 * @param sameChans Only return formats with same number of channels 734 * @return List of format names, must be freed by the caller 735 */ 736 static ObjList* allFormats(const ObjList* formats, bool existing = true, bool sameRate = true, bool sameChans = true); 737 738 /** 739 * Get a list of formats supported by transcoding for a given format list 740 * @param formats Data format names as comma separated list 741 * @param existing Also return formats already existing in the initial list 742 * @param sameRate Only return formats with same sampling rate 743 * @param sameChans Only return formats with same number of channels 744 * @return List of format names, must be freed by the caller 745 */ 746 static ObjList* allFormats(const String& formats, bool existing = true, bool sameRate = true, bool sameChans = true); 747 748 /** 749 * Check if bidirectional conversion can be performed by installed translators 750 * @param fmt1 Name of the first data format 751 * @param fmt2 Name of the second data format 752 * @return True if translators can be created for both directions 753 */ 754 static bool canConvert(const DataFormat& fmt1, const DataFormat& fmt2 = "slin"); 755 756 /** 757 * Finds the cost of a translator given the source and destination format names 758 * @param sFormat Name of the source format (data received from the consumer) 759 * @param dFormat Name of the destination format (data supplied to the source) 760 * @return Cost of best (cheapest) codec or -1 if no known codec exists 761 */ 762 static int cost(const DataFormat& sFormat, const DataFormat& dFormat); 763 764 /** 765 * Creates a translator given the source and destination format names 766 * @param sFormat Name of the source format (data received from the consumer) 767 * @param dFormat Name of the destination format (data supplied to the source) 768 * @return A pointer to a DataTranslator object or NULL if no known codec exists 769 */ 770 static DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat); 771 772 /** 773 * Attach a consumer to a source, possibly trough a chain of translators 774 * @param source Source to attach the chain to 775 * @param consumer Consumer where the chain ends 776 * @param override Attach chain for temporary source override 777 * @return True if successfull, false if no translator chain could be built 778 */ 779 static bool attachChain(DataSource* source, DataConsumer* consumer, bool override = false); 780 781 /** 782 * Detach a consumer from a source, possibly trough a chain of translators 783 * @param source Source to dettach the chain from 784 * @param consumer Consumer where the chain ends 785 * @return True if successfull, false if source and consumers were not attached 786 */ 787 static bool detachChain(DataSource* source, DataConsumer* consumer); 788 789 /** 790 * Set the length of the longest translator chain we are allowed to create 791 * @param maxChain Desired longest chain length 792 */ 793 static void setMaxChain(unsigned int maxChain); 794 795 protected: 796 /** 797 * Get access to the list of consumers of the data source 798 * @return Pointer to list entry of first consumer, NULL if none attached 799 */ getConsumers()800 inline ObjList* getConsumers() const 801 { return m_tsource ? m_tsource->m_consumers.skipNull() : 0; } 802 803 /** 804 * Synchronize the consumer with a source 805 * @param source Data source to copy the timestamp from 806 * @return True if we could synchronize with the source 807 */ 808 virtual bool synchronize(DataSource* source); 809 810 /** 811 * Install a Translator Factory in the list of known codecs 812 * @param factory A pointer to a TranslatorFactory instance 813 */ 814 static void install(TranslatorFactory* factory); 815 816 /** 817 * Remove a Translator Factory from the list of known codecs 818 * @param factory A pointer to a TranslatorFactory instance 819 */ 820 static void uninstall(TranslatorFactory* factory); 821 822 private: 823 DataTranslator(); // No default constructor please 824 static void compose(); 825 static void compose(TranslatorFactory* factory); 826 static bool canConvert(const FormatInfo* fmt1, const FormatInfo* fmt2); 827 DataSource* m_tsource; 828 static Mutex s_mutex; 829 static ObjList s_factories; 830 static unsigned int s_maxChain; 831 }; 832 833 /** 834 * A factory for constructing data translators by format name 835 * conversion of data from one type to another 836 * @short An unidirectional data translator (codec) 837 */ 838 class YATE_API TranslatorFactory : public GenObject 839 { 840 YNOCOPY(TranslatorFactory); // no automatic copies please 841 protected: 842 /** 843 * Constructor - registers the factory in the global list 844 * @param name Static name of the factory, used for debugging 845 */ 846 inline explicit TranslatorFactory(const char* name = 0) 847 : m_name(name ? name : "?") 848 { m_counter = Thread::getCurrentObjCounter(true); DataTranslator::install(this); } 849 850 public: 851 /** 852 * Destructor - unregisters from the global list 853 */ 854 virtual ~TranslatorFactory(); 855 856 /** 857 * Notification that another factory was removed from the list 858 * @param factory Pointer to the factory that just got removed 859 */ 860 virtual void removed(const TranslatorFactory* factory); 861 862 /** 863 * Creates a translator given the source and destination format names 864 * @param sFormat Name of the source format (data received from the consumer) 865 * @param dFormat Name of the destination format (data supplied to the source) 866 * @return A pointer to the end of a DataTranslator chain or NULL 867 */ 868 virtual DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat) = 0; 869 870 /** 871 * Get the capabilities table of this translator 872 * @return A pointer to the first element of the capabilities table 873 */ 874 virtual const TranslatorCaps* getCapabilities() const = 0; 875 876 /** 877 * Check if this factory can build a translator for given data formats 878 * @param sFormat Name of the source format 879 * @param dFormat Name of the destination format 880 * @return True if a conversion between formats is possible 881 */ 882 virtual bool converts(const DataFormat& sFormat, const DataFormat& dFormat) const; 883 884 /** 885 * Get the length of the translator chain built by this factory 886 * @return How many translators will build the factory 887 */ 888 virtual unsigned int length() const; 889 890 /** 891 * Check if a data format is used as intermediate in a translator chain 892 * @param info Format to check for 893 * @return True if the format is used internally as intermediate 894 */ 895 virtual bool intermediate(const FormatInfo* info) const; 896 897 /** 898 * Get the intermediate format used by a translator chain 899 * @return Pointer to intermediate format or NULL 900 */ 901 virtual const FormatInfo* intermediate() const; 902 903 /** 904 * Get the name of this factory, useful for debugging purposes 905 * @return Name of the factory as specified in the constructor 906 */ name()907 virtual const char* name() const 908 { return m_name; } 909 910 /** 911 * Retrive the objects counter associated to this factory 912 * @return Pointer to factory's objects counter or NULL 913 */ objectsCounter()914 inline NamedCounter* objectsCounter() const 915 { return m_counter; } 916 917 private: 918 const char* m_name; 919 NamedCounter* m_counter; 920 }; 921 922 /** 923 * The DataEndpoint holds an endpoint capable of performing unidirectional 924 * or bidirectional data transfers 925 * @short A data transfer endpoint capable of sending and/or receiving data 926 */ 927 class YATE_API DataEndpoint : public RefObject 928 { 929 YNOCOPY(DataEndpoint); // no automatic copies please 930 public: 931 /** 932 * Creates an empty data endpoint 933 */ 934 explicit DataEndpoint(CallEndpoint* call = 0, const char* name = "audio"); 935 936 /** 937 * Endpoint destruct notification, clears source and consumer 938 */ 939 virtual void destroyed(); 940 941 /** 942 * Get a pointer to a derived class given that class name 943 * @param name Name of the class we are asking for 944 * @return Pointer to the requested class or NULL if this object doesn't implement it 945 */ 946 virtual void* getObject(const String& name) const; 947 948 /** 949 * Get a string identification of the endpoint 950 * @return A reference to this endpoint's name 951 */ 952 virtual const String& toString() const; 953 954 /** 955 * Get the mutex that serializes access to this data endpoint, if any 956 * @return Pointer to the call's mutex object or NULL 957 */ 958 Mutex* mutex() const; 959 960 /** 961 * Get the big mutex that serializes access to all data endpoints 962 * @return A reference to the mutex 963 */ 964 static Mutex& commonMutex(); 965 966 /** 967 * Connect the source and consumer of the endpoint to a peer 968 * @param peer Pointer to the peer data endpoint 969 * @return True if connected, false if incompatible source/consumer 970 */ 971 bool connect(DataEndpoint* peer); 972 973 /** 974 * Disconnect from the connected endpoint 975 * @return True if the object was deleted, false if it still exists 976 */ 977 bool disconnect(); 978 979 /** 980 * Set the data source of this object 981 * @param source A pointer to the new source or NULL 982 */ 983 void setSource(DataSource* source = 0); 984 985 /** 986 * Get the data source of this object 987 * @return A pointer to the DataSource object or NULL 988 */ getSource()989 inline DataSource* getSource() const 990 { return m_source; } 991 992 /** 993 * Set the data consumer of this object 994 * @param consumer A pointer to the new consumer or NULL 995 */ 996 void setConsumer(DataConsumer* consumer = 0); 997 998 /** 999 * Get the data consumer of this object 1000 * @return A pointer to the DataConsumer object or NULL 1001 */ getConsumer()1002 inline DataConsumer* getConsumer() const 1003 { return m_consumer; } 1004 1005 /** 1006 * Set the data consumer for recording peer generated data. 1007 * This will be connected to the peer data source. 1008 * @param consumer A pointer to the new consumer or NULL 1009 */ 1010 void setPeerRecord(DataConsumer* consumer = 0); 1011 1012 /** 1013 * Get the data consumer used for recording peer generated data. 1014 * @return A pointer to the DataConsumer object or NULL 1015 */ getPeerRecord()1016 inline DataConsumer* getPeerRecord() const 1017 { return m_peerRecord; } 1018 1019 /** 1020 * Set the data consumer for recording local call generated data 1021 * This will be connected to the local data source. 1022 * @param consumer A pointer to the new consumer or NULL 1023 */ 1024 void setCallRecord(DataConsumer* consumer = 0); 1025 1026 /** 1027 * Get the data consumer used for recording local call generated data. 1028 * @return A pointer to the DataConsumer object or NULL 1029 */ getCallRecord()1030 inline DataConsumer* getCallRecord() const 1031 { return m_callRecord; } 1032 1033 /** 1034 * Clear a data node from any slot of this object 1035 * @param node Pointer to DataSource or DataConsumer to clear 1036 * @return True if the node was removed from at least one slot 1037 */ 1038 bool clearData(DataNode* node); 1039 1040 /** 1041 * Adds a data consumer to the list of sniffers of the local call data 1042 * @param sniffer Pointer to the DataConsumer to add to sniffer list 1043 * @return True if the sniffer was added to list, false if NULL or already added 1044 */ 1045 bool addSniffer(DataConsumer* sniffer); 1046 1047 /** 1048 * Remove a data consumer from the list of sniffers of the local call data 1049 * @param sniffer Pointer to the DataConsumer to remove from sniffer list 1050 * @return True if the sniffer was removed from list 1051 */ 1052 bool delSniffer(DataConsumer* sniffer); 1053 1054 /** 1055 * Find a sniffer by name 1056 * @param name Name of the sniffer to find 1057 * @param ref Increment the reference counter before returning 1058 * @return Pointer to DataConsumer or NULL if not found 1059 */ 1060 DataConsumer* getSniffer(const String& name, bool ref = false); 1061 1062 /** 1063 * Removes all sniffers from the list and dereferences them 1064 */ 1065 void clearSniffers(); 1066 1067 /** 1068 * Get a pointer to the peer endpoint 1069 * @return A pointer to the peer endpoint or NULL 1070 */ getPeer()1071 inline DataEndpoint* getPeer() const 1072 { return m_peer; } 1073 1074 /** 1075 * Get a pointer to the owner call 1076 * @return A pointer to the owner call or NULL 1077 */ getCall()1078 inline CallEndpoint* getCall() const 1079 { return m_call; } 1080 1081 /** 1082 * Get the name set in constructor 1083 * @return A reference to the name as hashed string 1084 */ name()1085 inline const String& name() const 1086 { return m_name; } 1087 1088 /** 1089 * Clear the owner call endpoint. 1090 * Works only if the caller provides the correct owner pointer 1091 * @param call Pointer to the call endpoint that is to be cleared 1092 */ clearCall(const CallEndpoint * call)1093 inline void clearCall(const CallEndpoint* call) 1094 { if (call == m_call) m_call = 0; } 1095 1096 /** 1097 * Modify data parameters 1098 * @param params The list of parameters to change 1099 * @return True if processed 1100 */ 1101 virtual bool control(NamedList& params); 1102 1103 protected: 1104 /** 1105 * Attempt to connect the endpoint to a peer of the same type 1106 * @param peer Pointer to the endpoint data driver 1107 * @return True if connected, false if failed native connection 1108 */ nativeConnect(DataEndpoint * peer)1109 virtual bool nativeConnect(DataEndpoint* peer) 1110 { return false; } 1111 1112 private: 1113 String m_name; 1114 DataSource* m_source; 1115 DataConsumer* m_consumer; 1116 DataEndpoint* m_peer; 1117 CallEndpoint* m_call; 1118 DataConsumer* m_peerRecord; 1119 DataConsumer* m_callRecord; 1120 ObjList m_sniffers; 1121 }; 1122 1123 /** 1124 * A class that holds common call control and data related features 1125 * @short An abstract call endpoint 1126 */ 1127 class YATE_API CallEndpoint : public RefObject 1128 { 1129 friend class DataEndpoint; 1130 YNOCOPY(CallEndpoint); // no automatic copies please 1131 private: 1132 CallEndpoint* m_peer; 1133 const void* m_lastPeer; 1134 String m_id; 1135 String m_lastPeerId; 1136 1137 protected: 1138 ObjList m_data; 1139 Mutex* m_mutex; 1140 1141 public: 1142 /** 1143 * Destruct notification, performs cleanups 1144 */ 1145 virtual void destroyed(); 1146 1147 /** 1148 * Get a pointer to a derived class given that class name 1149 * @param name Name of the class we are asking for 1150 * @return Pointer to the requested class or NULL if this object doesn't implement it 1151 */ 1152 virtual void* getObject(const String& name) const; 1153 1154 /** 1155 * Get a string representation of this channel 1156 * @return A reference to the name of this object 1157 */ toString()1158 virtual const String& toString() const 1159 { return m_id; } 1160 1161 /** 1162 * Get the unique channel identifier 1163 * @return A String holding the unique channel id 1164 */ id()1165 inline const String& id() const 1166 { return m_id; } 1167 1168 /** 1169 * Get the connected peer call 1170 * @return Pointer to connected peer call or NULL 1171 */ getPeer()1172 inline CallEndpoint* getPeer() const 1173 { return m_peer; } 1174 1175 /** 1176 * Get the connected peer call id in a caller supplied String 1177 * @param id String to fill in 1178 * @return True if the call endpoint has a peer 1179 */ 1180 bool getPeerId(String& id) const; 1181 1182 /** 1183 * Get the connected peer call id 1184 * @return Connected peer call id or empty string 1185 */ 1186 String getPeerId() const; 1187 1188 /** 1189 * Get the last connected peer call id in a caller supplied String 1190 * @param id String to fill in 1191 * @return True if the call endpoint ever had a peer 1192 */ 1193 bool getLastPeerId(String& id) const; 1194 1195 /** 1196 * Copy the current peer ID as the last connected peer ID, does nothing if not connected 1197 */ 1198 void setLastPeerId(); 1199 1200 /** 1201 * Get the mutex that serializes access to this call endpoint, if any 1202 * @return Pointer to the call's mutex object or NULL 1203 */ mutex()1204 inline Mutex* mutex() const 1205 { return m_mutex; } 1206 1207 /** 1208 * Get the big mutex that serializes access to all call endpoints 1209 * @return A reference to the mutex 1210 */ 1211 static Mutex& commonMutex(); 1212 1213 /** 1214 * Connect the call endpoint to a peer. 1215 * @param peer Pointer to the peer call endpoint. 1216 * @param reason Text that describes connect reason. 1217 * @param notify Call disconnected() notification method on old peer 1218 * @return True if connected, false if an error occured. 1219 */ 1220 bool connect(CallEndpoint* peer, const char* reason = 0, bool notify = true); 1221 1222 /** 1223 * Disconnect from the connected peer call endpoint. 1224 * @param reason Text that describes disconnect reason. 1225 * @param notify Call disconnected() notification method on old peer 1226 * @param params Optional pointer to extra parameters for disconnect cause 1227 * @return True if the object was deleted, false if it still exists 1228 */ 1229 inline bool disconnect(const char* reason = 0, bool notify = true, const NamedList* params = 0) 1230 { return disconnect(false,reason,notify,params); } 1231 1232 /** 1233 * Disconnect from the connected peer call endpoint and notify old peer. 1234 * @param reason Text that describes disconnect reason. 1235 * @param params Extra parameters for disconnect cause 1236 * @return True if the object was deleted, false if it still exists 1237 */ disconnect(const char * reason,const NamedList & params)1238 inline bool disconnect(const char* reason, const NamedList& params) 1239 { return disconnect(false,reason,true,¶ms); } 1240 1241 /** 1242 * Get a data endpoint of this object 1243 * @param type Type of data endpoint: "audio", "video", "text" 1244 * @return A pointer to the DataEndpoint object or NULL if not found 1245 */ 1246 DataEndpoint* getEndpoint(const String& type = CallEndpoint::audioType()) const; 1247 1248 /** 1249 * Get a data endpoint of this object, create if required 1250 * @param type Type of data endpoint: "audio", "video", "text" 1251 * @return A pointer to the DataEndpoint object or NULL if an error occured 1252 */ 1253 DataEndpoint* setEndpoint(const String& type = CallEndpoint::audioType()); 1254 1255 /** 1256 * Clear one or all data endpoints of this object 1257 * @param type Type of data endpoint: "audio", "video", "text", NULL to clear all 1258 */ 1259 void clearEndpoint(const String& type = String::empty()); 1260 1261 /** 1262 * Set a data source of this object 1263 * @param source A pointer to the new source or NULL 1264 * @param type Type of data node: "audio", "video", "text" 1265 */ 1266 void setSource(DataSource* source = 0, const String& type = CallEndpoint::audioType()); 1267 1268 /** 1269 * Get a data source of this object 1270 * @param type Type of data node: "audio", "video", "text" 1271 * @return A pointer to the DataSource object or NULL 1272 */ 1273 DataSource* getSource(const String& type = CallEndpoint::audioType()) const; 1274 1275 /** 1276 * Set the data consumer of this object 1277 * @param consumer A pointer to the new consumer or NULL 1278 * @param type Type of data node: "audio", "video", "text" 1279 */ 1280 void setConsumer(DataConsumer* consumer = 0, const String& type = CallEndpoint::audioType()); 1281 1282 /** 1283 * Get the data consumer of this object 1284 * @param type Type of data node: "audio", "video", "text" 1285 * @return A pointer to the DataConsumer object or NULL 1286 */ 1287 DataConsumer* getConsumer(const String& type = CallEndpoint::audioType()) const; 1288 1289 /** 1290 * Clear a data node from any slot of a DataEndpoint of this object 1291 * @param node Pointer to DataSource or DataConsumer to clear 1292 * @param type Type of data node: "audio", "video", "text" 1293 * @return True if the node was removed from at least one slot 1294 */ 1295 bool clearData(DataNode* node, const String& type = CallEndpoint::audioType()); 1296 1297 /** 1298 * Return the defaul audio type "audio" 1299 * @return Return a string naming the "audio" type 1300 */ 1301 static const String& audioType(); 1302 1303 protected: 1304 /** 1305 * Constructor 1306 */ 1307 CallEndpoint(const char* id = 0); 1308 1309 /** 1310 * Connect notification method. 1311 * @param reason Text that describes connect reason. 1312 */ connected(const char * reason)1313 virtual void connected(const char* reason) { } 1314 1315 /** 1316 * Disconnect notification method. 1317 * @param final True if this disconnect was called from the destructor. 1318 * @param reason Text that describes disconnect reason. 1319 */ disconnected(bool final,const char * reason)1320 virtual void disconnected(bool final, const char* reason) { } 1321 1322 /** 1323 * Set disconnect parameters 1324 * @param params Pointer to disconnect cause parameters, NULL to reset them 1325 */ setDisconnect(const NamedList * params)1326 virtual void setDisconnect(const NamedList* params) { } 1327 1328 /** 1329 * Set the peer call endpoint pointer. 1330 * @param peer A pointer to the new peer or NULL. 1331 * @param reason Text describing the reason in case of disconnect. 1332 * @param notify Call notification methods - connected() or disconnected() 1333 * @param params Optional pointer to extra parameters for disconnect cause 1334 */ 1335 void setPeer(CallEndpoint* peer, const char* reason = 0, bool notify = true, const NamedList* params = 0); 1336 1337 /** 1338 * Set a foreign data endpoint in this object 1339 * @param endPoint Data endpoint to set, will replace one with same type 1340 */ 1341 void setEndpoint(DataEndpoint* endPoint); 1342 1343 /** 1344 * Set a new ID for this call endpoint 1345 * @param newId New ID to set to this call 1346 */ 1347 virtual void setId(const char* newId); 1348 1349 private: 1350 bool disconnect(bool final, const char* reason, bool notify, const NamedList* params); 1351 }; 1352 1353 /** 1354 * Module is a descendent of Plugin specialized in implementing modules 1355 * @short A Plugin that implements a module 1356 */ 1357 class YATE_API Module : public Plugin, public Mutex, public MessageReceiver 1358 { 1359 YNOCOPY(Module); // no automatic copies please 1360 private: 1361 bool m_init; 1362 int m_relays; 1363 String m_type; 1364 Regexp m_filter; 1365 u_int64_t m_changed; 1366 static unsigned int s_delay; 1367 1368 public: 1369 /** 1370 * Get a pointer to a derived class given that class name 1371 * @param name Name of the class we are asking for 1372 * @return Pointer to the requested class or NULL if this object doesn't implement it 1373 */ 1374 virtual void* getObject(const String& name) const; 1375 1376 /** 1377 * Retrieve the type of the module 1378 * @return The module's type as String 1379 */ type()1380 inline const String& type() const 1381 { return m_type; } 1382 1383 /** 1384 * Mark the driver statistics "dirty" therefore triggring a delayed 1385 * status update. 1386 */ 1387 void changed(); 1388 1389 /** 1390 * Retrieve the global update notification delay 1391 * @return Update delay value in seconds 1392 */ updateDelay()1393 inline static unsigned int updateDelay() 1394 { return s_delay; } 1395 1396 /** 1397 * Set the global update notification delay 1398 * @param delay New update delay value in seconds, 0 to disable 1399 */ updateDelay(unsigned int delay)1400 inline static void updateDelay(unsigned int delay) 1401 { s_delay = delay; } 1402 1403 /** 1404 * Check if a debug filter is installed 1405 * @return True if debugging should be filtered 1406 */ filterInstalled()1407 inline bool filterInstalled() const 1408 { return !m_filter.null(); } 1409 1410 /** 1411 * Check by filter rule if debugging should be active 1412 * @param item Value of the item to match 1413 * @return True if debugging should be activated 1414 */ 1415 bool filterDebug(const String& item) const; 1416 1417 /** 1418 * Helper function to complete just one item on a command line 1419 * @param itemList Tab separated list of possible values to complete 1420 * @param item Item to possibly insert in the list 1421 * @param partWord Partial word to complete, may be empty 1422 * @return True if the item was added to list, false if it didn't match 1423 */ 1424 static bool itemComplete(String& itemList, const String& item, const String& partWord); 1425 1426 protected: 1427 /** 1428 * IDs of the installed relays 1429 */ 1430 enum { 1431 // Module messages 1432 Status = 0x00000001, 1433 Timer = 0x00000002, 1434 Level = 0x00000004, 1435 Command = 0x00000008, 1436 Help = 0x00000010, 1437 Halt = 0x00000020, 1438 Route = 0x00000040, 1439 Stop = 0x00000080, 1440 // Driver messages 1441 Execute = 0x00000100, 1442 Drop = 0x00000200, 1443 // Channel messages 1444 Locate = 0x00000400, 1445 Masquerade = 0x00000800, 1446 Ringing = 0x00001000, 1447 Answered = 0x00002000, 1448 Tone = 0x00004000, 1449 Text = 0x00008000, 1450 Progress = 0x00010000, 1451 Update = 0x00020000, 1452 Transfer = 0x00040000, 1453 Control = 0x00080000, 1454 // Instant messaging related 1455 MsgExecute = 0x00100000, 1456 // Last possible public ID 1457 PubLast = 0x00ffffff, 1458 // Private messages base ID 1459 Private = 0x01000000 1460 } RelayID; 1461 1462 /** 1463 * Find the name of a specific Relay ID 1464 * @param id RelayID of the message 1465 * @return Pointer to name of the message or NULL if not found 1466 */ 1467 static const char* messageName(int id); 1468 1469 /** 1470 * Find the ID or a specific Relay name 1471 * @param name Name of the Relay to search for 1472 * @return ID of the Relay, zero if not found 1473 */ relayId(const char * name)1474 static inline int relayId(const char* name) 1475 { return lookup(name,s_messages); } 1476 1477 /** 1478 * Constructor 1479 * @param name Plugin name of this driver 1480 * @param type Type of the driver: "misc", "route", etc. 1481 * @param earlyInit True to attempt to initialize module before others 1482 */ 1483 Module(const char* name, const char* type = 0, bool earlyInit = false); 1484 1485 /** 1486 * Destructor 1487 */ 1488 virtual ~Module(); 1489 1490 /** 1491 * This method is called to initialize the loaded module 1492 */ 1493 virtual void initialize(); 1494 1495 /** 1496 * Install standard message relays 1497 */ 1498 void setup(); 1499 1500 /** 1501 * Check if a specific relay ID is installed 1502 * @param id RelayID to test for 1503 * @return True if such a relay is installed 1504 */ relayInstalled(int id)1505 inline bool relayInstalled(int id) const 1506 { return (id & m_relays) != 0; } 1507 1508 /** 1509 * Install a standard message relay 1510 * @param id RelayID of the new relay to create 1511 * @param priority Priority of the handler, 0 = top 1512 * @return True if installed or already was one installed 1513 */ 1514 bool installRelay(int id, unsigned priority = 100); 1515 1516 /** 1517 * Install a standard message relay 1518 * @param name Name of the relay to create, must match a RelayID 1519 * @param priority Priority of the handler, 0 = top 1520 * @return True if installed or already was one installed 1521 */ 1522 bool installRelay(const char* name, unsigned priority = 100); 1523 1524 /** 1525 * Install a custom message relay 1526 * @param id RelayID of the new relay to create 1527 * @param name Name of the custom relay to create 1528 * @param priority Priority of the handler, 0 = top 1529 * @return True if installed or already was one installed 1530 */ 1531 bool installRelay(int id, const char* name, unsigned priority = 100); 1532 1533 /** 1534 * Install a custom message relay 1535 * @param relay Custom message relay 1536 * @return True if installed, false if there was already one with same ID 1537 */ 1538 bool installRelay(MessageRelay* relay); 1539 1540 /** 1541 * Uninstall a message relay 1542 * @param relay Pointer to message relay 1543 * @param delRelay True to delete the relay after removing it 1544 * @return True if uninstalled, false if if was not present 1545 */ 1546 bool uninstallRelay(MessageRelay* relay, bool delRelay = true); 1547 1548 /** 1549 * Uninstall a message relay 1550 * @param id RelayID to uninstall, relay will be deleted 1551 * @param delRelay True to delete the relay after removing it 1552 * @return True if uninstalled, false if if was not present 1553 */ 1554 bool uninstallRelay(int id, bool delRelay = true); 1555 1556 /** 1557 * Uninstall all installed relays in preparation for unloading 1558 * @return True if all relays were uninstalled, false if something wrong 1559 */ 1560 bool uninstallRelays(); 1561 1562 /** 1563 * Message receiver handler 1564 * @param msg The received message 1565 * @param id The identifier with which the relay was created 1566 * @return True to stop processing, false to try other handlers 1567 */ 1568 virtual bool received(Message &msg, int id); 1569 1570 /** 1571 * Opportunity to modify the update message 1572 * @param msg Status update message 1573 */ 1574 virtual void genUpdate(Message& msg); 1575 1576 /** 1577 * Timer message handler. 1578 * @param msg Time message 1579 */ 1580 virtual void msgTimer(Message& msg); 1581 1582 /** 1583 * Status message handler that is invoked only for matching messages. 1584 * @param msg Status message 1585 */ 1586 virtual void msgStatus(Message& msg); 1587 1588 /** 1589 * Routing message handler that is invoked for all call.route messages. 1590 * @param msg Call routing message 1591 * @return True to stop processing the message, false to try other handlers 1592 */ 1593 virtual bool msgRoute(Message& msg); 1594 1595 /** 1596 * Handler for special commands and line completion requests. 1597 * By default it calls @ref commandExecute() or @ref commandComplete(). 1598 * @param msg Command message 1599 * @return True to stop processing the message, false to try other handlers 1600 */ 1601 virtual bool msgCommand(Message& msg); 1602 1603 /** 1604 * Build the module identification part of the status answer 1605 * @param str String variable to fill up 1606 */ 1607 virtual void statusModule(String& str); 1608 1609 /** 1610 * Build the parameter reporting part of the status answer 1611 * @param str String variable to fill up 1612 */ 1613 virtual void statusParams(String& str); 1614 1615 /** 1616 * Build the details reporting part of the status answer 1617 * @param str String variable to fill up 1618 */ 1619 virtual void statusDetail(String& str); 1620 1621 /** 1622 * Execute a specific command 1623 * @param retVal String to append the textual command output to 1624 * @param line Command line to attempt to execute 1625 * @return True to stop processing the message, false to try other handlers 1626 */ 1627 virtual bool commandExecute(String& retVal, const String& line); 1628 1629 /** 1630 * Complete a command line 1631 * @param msg Message to return completion into 1632 * @param partLine Partial line to complete, excluding the last word 1633 * @param partWord Partial word to complete 1634 * @return True to stop processing the message, false to try other handlers 1635 */ 1636 virtual bool commandComplete(Message& msg, const String& partLine, const String& partWord); 1637 1638 /** 1639 * Set the local debugging level 1640 * @param msg Debug setting message 1641 * @param target String to match for local settings 1642 */ 1643 virtual bool setDebug(Message& msg, const String& target); 1644 1645 private: 1646 Module(); // no default constructor please 1647 static TokenDict s_messages[]; 1648 ObjList m_relayList; 1649 }; 1650 1651 /** 1652 * A class that holds common channel related features (a.k.a. call leg) 1653 * @short An abstract communication channel 1654 */ 1655 class YATE_API Channel : public CallEndpoint, public DebugEnabler, public MessageNotifier 1656 { 1657 friend class Driver; 1658 friend class Router; 1659 YNOCOPY(Channel); // no automatic copies please 1660 private: 1661 NamedList m_parameters; 1662 NamedList* m_chanParams; // Channel parameters to be set in all messages 1663 Driver* m_driver; 1664 bool m_outgoing; 1665 u_int64_t m_timeout; 1666 u_int64_t m_maxcall; 1667 u_int64_t m_maxPDD; // Timeout while waiting for some progress on outgoing calls 1668 u_int64_t m_dtmfTime; 1669 unsigned int m_toutAns; 1670 unsigned int m_dtmfSeq; 1671 String m_dtmfText; 1672 String m_dtmfDetected; 1673 1674 protected: 1675 String m_status; 1676 String m_address; 1677 String m_targetid; 1678 String m_billid; 1679 bool m_answered; 1680 1681 public: 1682 /** 1683 * Destructor 1684 */ 1685 virtual ~Channel(); 1686 1687 /** 1688 * Get a pointer to a derived class given that class name 1689 * @param name Name of the class we are asking for 1690 * @return Pointer to the requested class or NULL if this object doesn't implement it 1691 */ 1692 virtual void* getObject(const String& name) const; 1693 1694 /** 1695 * Get the big mutex that serializes access to all disconnect parameter lists 1696 * @return A reference to the mutex 1697 */ 1698 static Mutex& paramMutex(); 1699 1700 /** 1701 * Put channel variables into a message 1702 * @param msg Message to fill in 1703 * @param minimal True to fill in only a minimum of parameters 1704 */ 1705 virtual void complete(Message& msg, bool minimal = false) const; 1706 1707 /** 1708 * Create a filled notification message 1709 * @param name Name of the message to create 1710 * @param minimal Set to true to fill in only a minimum of parameters 1711 * @param data Set the channel as message data 1712 * @return A new allocated and parameter filled message 1713 */ 1714 Message* message(const char* name, bool minimal = false, bool data = false); 1715 1716 /** 1717 * Create a filled notification message, copy some parameters from another message 1718 * @param name Name of the message to create 1719 * @param original Parameters to copy from, can be NULL 1720 * @param params Comma separated list of parameters to copy, 1721 * if NULL will be taken from the "copyparams" parameter of original 1722 * @param minimal Set to true to fill in only a minimum of parameters 1723 * @param data Set the channel as message data 1724 * @return A new allocated and parameter filled message 1725 */ 1726 Message* message(const char* name, const NamedList* original, const char* params = 0, bool minimal = false, bool data = false); 1727 1728 /** 1729 * Create a filled notification message, copy some parameters from another message 1730 * @param name Name of the message to create 1731 * @param original Parameters to copy from 1732 * @param params Comma separated list of parameters to copy, 1733 * if NULL will be taken from the "copyparams" parameter of original 1734 * @param minimal Set to true to fill in only a minimum of parameters 1735 * @param data Set the channel as message data 1736 * @return A new allocated and parameter filled message 1737 */ 1738 inline Message* message(const char* name, const NamedList& original, const char* params = 0, bool minimal = false, bool data = false) 1739 { return message(name,&original,params,minimal,data); } 1740 1741 /** 1742 * Notification on remote call making some progress, not enabled by default 1743 * @param msg Notification message 1744 * @return True to stop processing the message, false to let it flow 1745 */ 1746 virtual bool msgProgress(Message& msg); 1747 1748 /** 1749 * Notification on remote ringing 1750 * @param msg Notification message 1751 * @return True to stop processing the message, false to let it flow 1752 */ 1753 virtual bool msgRinging(Message& msg); 1754 1755 /** 1756 * Notification on remote answered. Note that the answered flag will be set 1757 * @param msg Notification message 1758 * @return True to stop processing the message, false to let it flow 1759 */ 1760 virtual bool msgAnswered(Message& msg); 1761 1762 /** 1763 * Notification on remote tone(s) 1764 * @param msg Notification message 1765 * @param tone Pointer to the received tone(s) 1766 * @return True to stop processing the message, false to let it flow 1767 */ 1768 virtual bool msgTone(Message& msg, const char* tone); 1769 1770 /** 1771 * Notification on remote text messaging (sms) 1772 * @param msg Notification message 1773 * @param text Pointer to the received text 1774 * @return True to stop processing the message, false to let it flow 1775 */ 1776 virtual bool msgText(Message& msg, const char* text); 1777 1778 /** 1779 * Notification on current call drop request 1780 * @param msg Notification message 1781 * @param reason Pointer to drop reason text or NULL if none provided 1782 * @return True if initiated call drop, false if failed 1783 */ 1784 virtual bool msgDrop(Message& msg, const char* reason); 1785 1786 /** 1787 * Notification on native transfer request 1788 * @param msg Notification message 1789 * @return True to stop processing the message, false to let it flow 1790 */ 1791 virtual bool msgTransfer(Message& msg); 1792 1793 /** 1794 * Notification on call parameters update request 1795 * @param msg Notification message 1796 * @return True to stop processing the message, false to let it flow 1797 */ 1798 virtual bool msgUpdate(Message& msg); 1799 1800 /** 1801 * Notification on message masquerade as channel request 1802 * @param msg Message already modified to masquerade as this channel 1803 * @return True to stop processing the message, false to masquerade it 1804 */ 1805 virtual bool msgMasquerade(Message& msg); 1806 1807 /** 1808 * Status message handler that is invoked only for messages to this channel 1809 * @param msg Status message 1810 */ 1811 virtual void msgStatus(Message& msg); 1812 1813 /** 1814 * Control message handler that is invoked only for messages to this channel 1815 * @param msg Control message 1816 * @return True to stop processing the message, false to let it flow 1817 */ 1818 virtual bool msgControl(Message& msg); 1819 1820 /** 1821 * Timer check method, by default handles channel timeouts 1822 * @param msg Timer message 1823 * @param tmr Current time against which timers are compared 1824 */ 1825 virtual void checkTimers(Message& msg, const Time& tmr); 1826 1827 /** 1828 * Notification on progress of prerouting incoming call 1829 * @param msg Notification call.preroute message just after being dispatched 1830 * @param handled True if a handler claimed having handled prerouting 1831 * @return True to continue with the call, false to abort the route 1832 */ 1833 virtual bool callPrerouted(Message& msg, bool handled); 1834 1835 /** 1836 * Notification on progress of routing incoming call 1837 * @param msg Notification call.route message just after being dispatched 1838 * @return True to continue with the call, false to abort the route 1839 */ 1840 virtual bool callRouted(Message& msg); 1841 1842 /** 1843 * Notification on success of incoming call 1844 * @param msg Notification call.execute message just after being dispatched 1845 */ 1846 virtual void callAccept(Message& msg); 1847 1848 /** 1849 * Notification on failure of incoming call 1850 * @param error Standard error keyword 1851 * @param reason Textual failure reason 1852 * @param msg Pointer to message causing the rejection, if any 1853 */ 1854 virtual void callRejected(const char* error, const char* reason = 0, const Message* msg = 0); 1855 1856 /** 1857 * Common processing after connecting the outgoing call, should be called 1858 * from Driver's msgExecute() 1859 * @param msg Notification call.execute message while being dispatched 1860 */ 1861 virtual void callConnect(Message& msg); 1862 1863 /** 1864 * Set the local debugging level 1865 * @param msg Debug setting message 1866 */ 1867 virtual bool setDebug(Message& msg); 1868 1869 /** 1870 * Get the current status of the channel 1871 * This method is thread safe 1872 * @param buf Destination buffer 1873 * @param append True to append to destination buffer, false to set (replace contents) 1874 * @return Destination buffer reference 1875 */ 1876 inline String& getStatus(String& buf, bool append = true) const { 1877 Lock lck(chanDataMutex()); 1878 if (append) 1879 buf += m_status; 1880 else 1881 buf = m_status; 1882 return buf; 1883 } 1884 1885 /** 1886 * Get the current status of the channel. Add it in list parameters 1887 * This method is thread safe 1888 * @param list Destination list 1889 * @param param Parameter name 1890 * @param append True to append parameter to list, false to replace 1891 */ 1892 inline void putStatus(NamedList& list, const char* param = "status", bool append = true) const { 1893 NamedString* ns = new NamedString(param); 1894 getStatus(*ns); 1895 if (append) 1896 list.addParam(ns); 1897 else 1898 list.setParam(ns); 1899 } 1900 1901 /** 1902 * Get the current link address of the channel 1903 * @return The protocol dependent address as String 1904 */ address()1905 inline const String& address() const 1906 { return m_address; } 1907 1908 /** 1909 * Get the direction of the channel 1910 * @return True if the channel is an outgoing call (generated locally) 1911 */ isOutgoing()1912 inline bool isOutgoing() const 1913 { return m_outgoing; } 1914 1915 /** 1916 * Get the direction of the channel 1917 * @return True if the channel is an incoming call (generated remotely) 1918 */ isIncoming()1919 inline bool isIncoming() const 1920 { return !m_outgoing; } 1921 1922 /** 1923 * Check if the call was answered or not 1924 * @return True if the call was answered 1925 */ isAnswered()1926 inline bool isAnswered() const 1927 { return m_answered; } 1928 1929 /** 1930 * Get the direction of the channel as string 1931 * @return "incoming" or "outgoing" according to the direction 1932 */ 1933 const char* direction() const; 1934 1935 /** 1936 * Get the driver of this channel 1937 * @return Pointer to this channel's driver 1938 */ driver()1939 inline Driver* driver() const 1940 { return m_driver; } 1941 1942 /** 1943 * Get the time this channel will time out 1944 * @return Timeout time or zero if no timeout 1945 */ timeout()1946 inline u_int64_t timeout() const 1947 { return m_timeout; } 1948 1949 /** 1950 * Set the time this channel will time out 1951 * @param tout New timeout time or zero to disable 1952 */ timeout(u_int64_t tout)1953 inline void timeout(u_int64_t tout) 1954 { m_timeout = tout; } 1955 1956 /** 1957 * Get the time this channel will time out on outgoing calls 1958 * @return Timeout time or zero if no timeout 1959 */ maxcall()1960 inline u_int64_t maxcall() const 1961 { return m_maxcall; } 1962 1963 /** 1964 * Set the time this channel will time out on outgoing calls 1965 * @param tout New timeout time or zero to disable 1966 */ maxcall(u_int64_t tout)1967 inline void maxcall(u_int64_t tout) 1968 { m_maxcall = tout; } 1969 1970 /** 1971 * Set the time this channel will time out on outgoing calls 1972 * @param msg Reference of message possibly holding "maxcall" parameter 1973 * @param defTout Default timeout to apply, negative to not alter 1974 */ 1975 inline void setMaxcall(const Message& msg, int defTout = -1) 1976 { setMaxcall(&msg,defTout); } 1977 1978 /** 1979 * Set the time this channel will time out on outgoing calls 1980 * @param msg Pointer to message possibly holding "maxcall" parameter 1981 * @param defTout Default timeout to apply, negative to not alter 1982 */ 1983 void setMaxcall(const Message* msg, int defTout = -1); 1984 1985 /** 1986 * Get the time this channel will time out while waiting for some progress 1987 * on outgoing calls 1988 * @return Timeout time or zero if no timeout 1989 */ maxPDD()1990 inline u_int64_t maxPDD() const 1991 { return m_maxPDD; } 1992 1993 /** 1994 * Set the time this channel will time out while waiting for some progress 1995 * on outgoing calls 1996 * @param tout New timeout time or zero to disable 1997 */ maxPDD(u_int64_t tout)1998 inline void maxPDD(u_int64_t tout) 1999 { m_maxPDD = tout; } 2000 2001 /** 2002 * Set the time this channel will time out while waiting for some progress 2003 * on outgoing calls 2004 * @param msg Reference of message possibly holding "maxpdd" parameter 2005 */ 2006 void setMaxPDD(const Message& msg); 2007 2008 /** 2009 * Get the connected channel identifier. 2010 * @return A String holding the unique channel id of the target or an empty 2011 * string if this channel is not connected to a target. 2012 */ targetid()2013 inline const String& targetid() const 2014 { return m_targetid; } 2015 2016 /** 2017 * Get the billing identifier. 2018 * @return An identifier of the call or account that will be billed for 2019 * calls made by this channel. 2020 */ billid()2021 inline const String& billid() const 2022 { return m_billid; } 2023 2024 /** 2025 * Add the channel to the parent driver list 2026 * This method must be called exactly once after the object is fully constructed 2027 */ 2028 void initChan(); 2029 2030 /** 2031 * Start a routing thread for this channel, dereference dynamic channels 2032 * @param msg Pointer to message to route, typically a "call.route", will be 2033 * destroyed after routing fails or completes 2034 * @return True if routing thread started successfully, false if failed 2035 */ 2036 bool startRouter(Message* msg); 2037 2038 /** 2039 * Allocate an unique (per engine run) call ID 2040 * @return Unique call ID number 2041 */ 2042 static unsigned int allocId(); 2043 2044 /** 2045 * Enable or disable debugging according to driver's filter rules 2046 * @param item Value of the item to match 2047 */ 2048 void filterDebug(const String& item); 2049 2050 /** 2051 * Get the disconnect parameters list 2052 * @return Constant reference to disconnect parameters 2053 */ parameters()2054 inline const NamedList& parameters() const 2055 { return m_parameters; } 2056 2057 /** 2058 * Set channel parameters 2059 * @param list List of parameters 2060 * @param in True if set for incoming channel (called for (pre)routed/rejected,accepted) 2061 */ 2062 inline void setChanParams(const NamedList& list, bool in = false) { 2063 const String& pref = in ? list[YSTRING("ichanparams-prefix")] : list[YSTRING("chanparams-prefix")]; 2064 if (!pref) 2065 return; 2066 Lock lck(paramMutex()); 2067 if (!m_chanParams) 2068 m_chanParams = new NamedList(""); 2069 m_chanParams->copySubParams(list,pref,true,true); 2070 } 2071 2072 /** 2073 * Copy channel parameters 2074 * @param list Destination list 2075 */ copyChanParams(NamedList & list)2076 inline void copyChanParams(NamedList& list) const { 2077 if (!m_chanParams) 2078 return; 2079 Lock lck(paramMutex()); 2080 list.copyParams(*m_chanParams); 2081 } 2082 2083 /** 2084 * Notification for dispatched messages 2085 * @param msg Message that was dispatched 2086 * @param handled Result of handling the message 2087 */ 2088 virtual void dispatched(const Message& msg, bool handled); 2089 2090 protected: 2091 /** 2092 * Constructor 2093 */ 2094 Channel(Driver* driver, const char* id = 0, bool outgoing = false); 2095 2096 /** 2097 * Alternate constructor provided for convenience 2098 */ 2099 Channel(Driver& driver, const char* id = 0, bool outgoing = false); 2100 2101 /** 2102 * Perform destruction time cleanup. You can call this method earlier 2103 * if destruction is to be postponed. 2104 */ 2105 void cleanup(); 2106 2107 /** 2108 * Remove the channel from the parent driver list 2109 */ 2110 void dropChan(); 2111 2112 /** 2113 * This method is overriden to safely remove the channel from the parent 2114 * driver list before actually destroying the channel. 2115 */ 2116 virtual void zeroRefs(); 2117 2118 /** 2119 * Connect notification method. 2120 * @param reason Text that describes connect reason. 2121 */ 2122 virtual void connected(const char* reason); 2123 2124 /** 2125 * Disconnect notification method. 2126 * @param final True if this disconnect was called from the destructor. 2127 * @param reason Text that describes disconnect reason. 2128 */ 2129 virtual void disconnected(bool final, const char* reason); 2130 2131 /** 2132 * Set disconnect parameters 2133 * @param params Pointer to disconnect cause parameters, NULL to reset them 2134 */ 2135 virtual void setDisconnect(const NamedList* params); 2136 2137 /** 2138 * Notification after chan.disconnected handling 2139 * @param msg The chan.disconnected message 2140 * @param handled True if the message was handled 2141 */ 2142 virtual void endDisconnect(const Message& msg, bool handled); 2143 2144 /** 2145 * Set a new ID for this channel 2146 * @param newId New ID to set to this channel 2147 */ 2148 virtual void setId(const char* newId); 2149 2150 /** 2151 * Create a properly populated chan.disconnect message 2152 * @param reason Channel disconnect reason if available 2153 * @return A new allocated and parameter filled chan.disconnected message 2154 */ 2155 virtual Message* getDisconnect(const char* reason); 2156 2157 /** 2158 * Set the current status of the channel. 2159 * Note that a value of "answered" will set the answered flag 2160 * @param newstat The new status as String 2161 */ 2162 void status(const char* newstat); 2163 2164 /** 2165 * Retrieve Channel status 2166 * This method is not thread safe 2167 * @return Channel status 2168 */ getStatus()2169 inline const String& getStatus() const 2170 { return m_status; } 2171 2172 /** 2173 * Build the parameter reporting part of the status answer 2174 * @param str String variable to fill up 2175 */ 2176 virtual void statusParams(String& str); 2177 2178 /** 2179 * Set the current direction of the channel 2180 * @param outgoing True if this is an outgoing call channel 2181 */ 2182 inline void setOutgoing(bool outgoing = true) 2183 { m_outgoing = outgoing; } 2184 2185 /** 2186 * Add sequence number to chan.dtmf message, check for duplicates 2187 * @param msg chan.dtmf message to apply sequence number 2188 * @return True if the message is a duplicate (same tone, different method) 2189 */ 2190 bool dtmfSequence(Message& msg); 2191 2192 /** 2193 * Add sequence number to chan.dtmf and enqueue it, delete if duplicate 2194 * @param msg chan.dtmf message to sequence and enqueue 2195 * @return True if the message was enqueued, false if was a duplicate 2196 */ 2197 bool dtmfEnqueue(Message* msg); 2198 2199 /** 2200 * Attempt to install an override data source to send DTMF inband. 2201 * Needs a tone generator module capable to override with "tone/dtmfstr/xyz" 2202 * @param tone Pointer to the tone sequence to send 2203 * @return True on success 2204 */ 2205 bool dtmfInband(const char* tone); 2206 2207 /** 2208 * Attempt to install a data sniffer to detect inband tones 2209 * Needs a tone detector module capable of attaching sniffer consumers. 2210 * @param sniffer Name of the sniffer to install, default will detect all tones 2211 * @return True on success 2212 */ 2213 bool toneDetect(const char* sniffer = 0); 2214 2215 /** 2216 * Get the disconnect parameters list 2217 * @return Reference to disconnect parameters 2218 */ parameters()2219 inline NamedList& parameters() 2220 { return m_parameters; } 2221 2222 private: 2223 void init(); 2224 Channel(); // no default constructor please 2225 static Mutex s_chanDataMutex; 2226 // Just in case we are going to (re)move the channel data mutex! chanDataMutex()2227 static inline Mutex* chanDataMutex() 2228 { return &s_chanDataMutex; } 2229 }; 2230 2231 /** 2232 * Driver is a module specialized for implementing channel drivers 2233 * @short A Channel driver module 2234 */ 2235 class YATE_API Driver : public Module 2236 { 2237 friend class Router; 2238 friend class Channel; 2239 2240 private: 2241 bool m_init; 2242 bool m_varchan; 2243 String m_prefix; 2244 ObjList m_chans; 2245 int m_routing; 2246 int m_routed; 2247 int m_total; 2248 unsigned int m_nextid; 2249 int m_timeout; 2250 int m_maxroute; 2251 int m_maxchans; 2252 int m_chanCount; 2253 bool m_dtmfDups; 2254 volatile bool m_doExpire; 2255 2256 public: 2257 /** 2258 * Get a pointer to a derived class given that class name 2259 * @param name Name of the class we are asking for 2260 * @return Pointer to the requested class or NULL if this object doesn't implement it 2261 */ 2262 virtual void* getObject(const String& name) const; 2263 2264 /** 2265 * Retrieve the prefix that is used as base for all channels 2266 * @return The driver's prefix 2267 */ prefix()2268 inline const String& prefix() const 2269 { return m_prefix; } 2270 2271 /** 2272 * Check if this driver is for dynamic (variable number) channels 2273 * @return True if the channels are dynamic, false for fixed 2274 */ varchan()2275 inline bool varchan() const 2276 { return m_varchan; } 2277 2278 /** 2279 * Get the list of channels of this driver 2280 * @return A reference to the channel list 2281 */ channels()2282 inline ObjList& channels() 2283 { return m_chans; } 2284 2285 /** 2286 * Find a channel by id 2287 * @param id Unique identifier of the channel to find 2288 * @return Pointer to the channel or NULL if not found 2289 */ 2290 virtual Channel* find(const String& id) const; 2291 2292 /** 2293 * Check if the driver is actively used. 2294 * @return True if the driver is in use, false if should be ok to restart 2295 */ 2296 virtual bool isBusy() const; 2297 2298 /** 2299 * Drop all current channels 2300 * @param msg Notification message 2301 */ 2302 virtual void dropAll(Message &msg); 2303 2304 /** 2305 * Check if new connections can be accepted 2306 * @param routers Set to true to check routing threads for incoming connections 2307 * @return True if at least one new connection can be accepted, false if not 2308 */ 2309 virtual bool canAccept(bool routers = true); 2310 2311 /** 2312 * Check if new incoming connections can be routed 2313 * @return True if at least one new connection can be routed, false if not 2314 */ 2315 virtual bool canRoute(); 2316 2317 /** 2318 * Get the next unique numeric id from a sequence 2319 * @return A driver unique number that increments by 1 at each call 2320 */ 2321 unsigned int nextid(); 2322 2323 /** 2324 * Get the current (last used) unique numeric id from a sequence 2325 * @return The driver unique number 2326 */ lastid()2327 inline unsigned int lastid() const 2328 { return m_nextid; } 2329 2330 /** 2331 * Get the default driver timeout 2332 * @return Timeout value in milliseconds 2333 */ timeout()2334 inline int timeout() const 2335 { return m_timeout; } 2336 2337 /** 2338 * Get the number of calls currently in the routing stage 2339 * @return Number of router threads currently running 2340 */ routing()2341 inline int routing() const 2342 { return m_routing; } 2343 2344 /** 2345 * Get the number of calls successfully routed 2346 * @return Number of calls that have gone past the routing stage 2347 */ routed()2348 inline int routed() const 2349 { return m_routed; } 2350 2351 /** 2352 * Get the total number of calls ever created 2353 * @return Number of channels ever created for this driver 2354 */ total()2355 inline int total() const 2356 { return m_total; } 2357 2358 /** 2359 * Get the number of running channels 2360 * @return Number of channels running at this time 2361 */ chanCount()2362 inline int chanCount() const 2363 { return m_chanCount; } 2364 2365 /** 2366 * Get the maximum number of running channels for this driver 2367 * @return Maximum number of calls to run simultaneously, zero to accept all 2368 */ maxChans()2369 inline int maxChans() const 2370 { return m_maxchans; } 2371 2372 protected: 2373 /** 2374 * Constructor 2375 * @param name Plugin name of this driver 2376 * @param type Type of the driver: "fixchans", "varchans", etc. 2377 */ 2378 Driver(const char* name, const char* type = 0); 2379 2380 /** 2381 * This method is called to initialize the loaded module 2382 */ 2383 virtual void initialize(); 2384 2385 /** 2386 * Install standard message relays and set up the prefix 2387 * @param prefix Prefix to use with channels of this driver 2388 * @param minimal Install just a minimal set of message relays 2389 */ 2390 void setup(const char* prefix = 0, bool minimal = false); 2391 2392 /** 2393 * Message receiver handler 2394 * @param msg The received message 2395 * @param id The identifier with which the relay was created 2396 * @return True to stop processing, false to try other handlers 2397 */ 2398 virtual bool received(Message &msg, int id); 2399 2400 /** 2401 * Opportunity to modify the update message 2402 * @param msg Status update message 2403 */ 2404 virtual void genUpdate(Message& msg); 2405 2406 /** 2407 * Check if driver owns a client line (registered to an external server) 2408 * @param line Name of the line to check 2409 * @return True if this driver owns line with the specified name 2410 * 2411 */ 2412 virtual bool hasLine(const String& line) const; 2413 2414 /** 2415 * Routing message handler. The default implementation routes to this 2416 * driver if it owns a line named in the "account" or "line" parameter. 2417 * @param msg Call routing message 2418 * @return True to stop processing the message, false to try other handlers 2419 */ 2420 virtual bool msgRoute(Message& msg); 2421 2422 /** 2423 * Create an outgoing calling channel 2424 * @param msg Call execute message 2425 * @param dest Destination of the new call 2426 * @return True if outgoing call was created 2427 */ 2428 virtual bool msgExecute(Message& msg, String& dest) = 0; 2429 2430 /** 2431 * Complete a command line 2432 * @param msg Message to return completion into 2433 * @param partLine Partial line to complete, excluding the last word 2434 * @param partWord Partial word to complete 2435 * @return True to stop processing the message, false to try other handlers 2436 */ 2437 virtual bool commandComplete(Message& msg, const String& partLine, const String& partWord); 2438 2439 /** 2440 * Build the module identification part of the status answer 2441 * @param str String variable to fill up 2442 */ 2443 virtual void statusModule(String& str); 2444 2445 /** 2446 * Build the parameter reporting part of the status answer 2447 * @param str String variable to fill up 2448 */ 2449 virtual void statusParams(String& str); 2450 2451 /** 2452 * Build the channel list part of the status answer 2453 * @param str String variable to fill up 2454 */ 2455 virtual void statusDetail(String& str); 2456 2457 /** 2458 * Set the local debugging level 2459 * @param msg Debug setting message 2460 * @param target String to match for local settings 2461 */ 2462 virtual bool setDebug(Message& msg, const String& target); 2463 2464 /** 2465 * Load the global limits from the main config file 2466 */ 2467 virtual void loadLimits(); 2468 2469 /** 2470 * Module is able to simulate a call without generating anything at protocol layer 2471 * @return True if module is able 2472 */ canStopCall()2473 virtual bool canStopCall() const 2474 { return false; } 2475 2476 /** 2477 * Set if this driver is for dynamic (variable number) channels 2478 * @param variable True if the channels are dynamic, false for fixed 2479 */ varchan(bool variable)2480 inline void varchan(bool variable) 2481 { m_varchan = variable; } 2482 2483 /** 2484 * Set the default driver timeout 2485 * @param tout New timeout in milliseconds or zero to disable 2486 */ timeout(int tout)2487 inline void timeout(int tout) 2488 { m_timeout = tout; } 2489 2490 /** 2491 * Set the maximum number of routing messages for this driver 2492 * @param ncalls Number of calls to route simultaneously, zero to accept all 2493 */ maxRoute(int ncalls)2494 inline void maxRoute(int ncalls) 2495 { m_maxroute = ncalls; } 2496 2497 /** 2498 * Set the maximum number of running channels for this driver 2499 * @param ncalls Number of calls to run simultaneously, zero to accept all 2500 */ maxChans(int ncalls)2501 inline void maxChans(int ncalls) 2502 { m_maxchans = ncalls; } 2503 2504 /** 2505 * Set the DTMF duplicates allowed flag 2506 * @param duplicates True to allow DTMF duplicate messages 2507 */ dtmfDups(bool duplicates)2508 inline void dtmfDups(bool duplicates) 2509 { m_dtmfDups = duplicates; } 2510 2511 private: 2512 Driver(); // no default constructor please 2513 }; 2514 2515 /** 2516 * Asynchronous call routing thread 2517 * @short Call routing thread 2518 */ 2519 class YATE_API Router : public Thread 2520 { 2521 YNOCOPY(Router); // no automatic copies please 2522 private: 2523 Driver* m_driver; 2524 String m_id; 2525 Message* m_msg; 2526 2527 public: 2528 /** 2529 * Constructor - creates a new routing thread 2530 * @param driver Pointer to the driver that asked for routing 2531 * @param id Unique identifier of the channel being routed 2532 * @param msg Pointer to an already filled message 2533 */ 2534 Router(Driver* driver, const char* id, Message* msg); 2535 2536 /** 2537 * Main thread running method 2538 */ 2539 virtual void run(); 2540 2541 /** 2542 * Actual routing method 2543 * @return True if call was successfully routed 2544 */ 2545 virtual bool route(); 2546 2547 /** 2548 * Thread cleanup handler 2549 */ 2550 virtual void cleanup(); 2551 2552 protected: 2553 /** 2554 * Get the routed channel identifier 2555 * @return Unique id of the channel being routed 2556 */ id()2557 const String& id() const 2558 { return m_id; } 2559 }; 2560 2561 /** 2562 * This helper class holds generic account parameters that are applied to calls 2563 * @short Settings for an account handling calls 2564 */ 2565 class YATE_API CallAccount 2566 { 2567 YNOCOPY(CallAccount); 2568 private: 2569 Mutex* m_mutex; 2570 NamedList m_inbParams; 2571 NamedList m_outParams; 2572 NamedList m_regParams; 2573 2574 public: 2575 /** 2576 * Make a copy of the inbound and outbound parameter templates 2577 * @param params List of parameters to copy from 2578 */ 2579 void pickAccountParams(const NamedList& params); 2580 2581 2582 /** 2583 * Patch the inbound call parameters 2584 * @param params List of parameters to be patched 2585 */ 2586 void setInboundParams(NamedList& params); 2587 2588 /** 2589 * Patch the outbound call parameters 2590 * @param params List of parameters to be patched 2591 */ 2592 void setOutboundParams(NamedList& params); 2593 2594 /** 2595 * Patch registration parameters 2596 * @param params List of parameters to be patched 2597 */ 2598 void setRegisterParams(NamedList& params); 2599 2600 /** 2601 * Accessor for the inbound call parameters list 2602 * @return Reference to the inbound call parameters 2603 */ inboundParams()2604 inline const NamedList& inboundParams() const 2605 { return m_inbParams; } 2606 2607 /** 2608 * Accessor for the outbound call parameters list 2609 * @return Reference to the outbound call parameters 2610 */ outboundParams()2611 inline const NamedList& outboundParams() const 2612 { return m_outParams; } 2613 2614 /** 2615 * Accessor for the registration parameters list 2616 * @return Reference to the registration parameters 2617 */ registerParams()2618 inline const NamedList& registerParams() const 2619 { return m_regParams; } 2620 2621 protected: 2622 /** 2623 * Constructor 2624 * @param mutex The mutex that is used to lock object's variables 2625 */ CallAccount(Mutex * mutex)2626 inline CallAccount(Mutex* mutex) 2627 : m_mutex(mutex), m_inbParams(""), m_outParams(""), m_regParams("") 2628 { } 2629 }; 2630 2631 /** 2632 * Find if a string appears to be an E164 phone number 2633 * @param str String to check 2634 * @return True if str appears to be a valid E164 number 2635 */ 2636 YATE_API bool isE164(const char* str); 2637 2638 }; // namespace TelEngine 2639 2640 #endif /* __YATEPHONE_H */ 2641 2642 /* vi: set ts=8 sw=4 sts=4 noet: */ 2643