1 /** 2 * yateiax.h 3 * Yet Another IAX2 Stack 4 * This file is part of the YATE Project http://YATE.null.ro 5 * 6 * Yet Another Telephony Engine - a fully featured software PBX and IVR 7 * Copyright (C) 2004-2014 Null Team 8 * 9 * This software is distributed under multiple licenses; 10 * see the COPYING file in the main directory for licensing 11 * information for this specific distribution. 12 * 13 * This use of this software may be subject to additional restrictions. 14 * See the LEGAL file in the main directory for details. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 #ifndef __YATEIAX_H 22 #define __YATEIAX_H 23 24 #include <yateclass.h> 25 26 #ifdef _WINDOWS 27 28 #ifdef LIBYIAX_EXPORTS 29 #define YIAX_API __declspec(dllexport) 30 #else 31 #ifndef LIBYIAX_STATIC 32 #define YIAX_API __declspec(dllimport) 33 #endif 34 #endif 35 36 #endif /* _WINDOWS */ 37 38 #ifndef YIAX_API 39 #define YIAX_API 40 #endif 41 42 /** 43 * Holds all Telephony Engine related classes. 44 */ 45 namespace TelEngine { 46 47 class IAXInfoElement; // A single IAX2 Information Element 48 class IAXInfoElementString; // A single IAX2 text Information Element 49 class IAXInfoElementNumeric; // A single IAX2 numeric Information Element 50 class IAXInfoElementBinary; // A single IAX2 numeric Information Element 51 class IAXIEList; // Information Element container 52 class IAXAuthMethod; // Wrapper class for authentication methods values 53 class IAXFormatDesc; // IAX format description 54 class IAXFormat; // Wrapper class for formats 55 class IAXControl; // Wrapper class for subclasses of frames of type IAX 56 class IAXFrame; // This class holds an IAX frame 57 class IAXFullFrame; // This class holds an IAX full frame 58 class IAXFrameOut; // This class holds an outgoing IAX full frame 59 class IAXTrunkInfo; // Trunk info 60 class IAXMetaTrunkFrame; // Meta trunk frame 61 class IAXMediaData; // IAX2 transaction media data 62 class IAXTransaction; // An IAX2 transaction 63 class IAXEvent; // Event class 64 class IAXEngine; // IAX engine 65 66 #define IAX_PROTOCOL_VERSION 0x0002 // Protocol version 67 #define IAX2_MAX_CALLNO 32767 // Max call number value 68 #define IAX2_MAX_TRANSINFRAMELIST 127 // Max transaction incoming frame list 69 70 // Trunk frame header length 71 #define IAX2_TRUNKFRAME_HEADERLENGTH 8 72 // Trunk frame length 73 #define IAX2_TRUNKFRAME_LEN_MIN 20 // 16 bytes: meta header + miniframe with timestamps header 74 #define IAX2_TRUNKFRAME_LEN_DEF 1400 75 // Trunk frame send interval in milliseconds 76 #define IAX2_TRUNKFRAME_SEND_MIN 5 77 #define IAX2_TRUNKFRAME_SEND_DEF 20 78 79 // Frame retransmission 80 #define IAX2_RETRANS_COUNT_MIN 1 81 #define IAX2_RETRANS_COUNT_MAX 10 82 #define IAX2_RETRANS_COUNT_DEF 4 83 #define IAX2_RETRANS_INTERVAL_MIN 200 84 #define IAX2_RETRANS_INTERVAL_MAX 5000 85 #define IAX2_RETRANS_INTERVAL_DEF 500 86 87 // Ping 88 #define IAX2_PING_INTERVAL_MIN 10000 89 #define IAX2_PING_INTERVAL_DEF 20000 90 91 // Sent challenge timeout 92 #define IAX2_CHALLENGETOUT_MIN 5000 93 #define IAX2_CHALLENGETOUT_DEF 30000 94 95 /** 96 * This class holds a single Information Element with no data 97 * @short A single IAX2 Information Element 98 */ 99 class YIAX_API IAXInfoElement : public RefObject 100 { 101 public: 102 /** 103 * Information Element enumeration types 104 */ 105 enum Type { 106 textframe = 0x00, // Text Used internally only to generate an event of type Text 107 CALLED_NUMBER = 0x01, // Text 108 CALLING_NUMBER = 0x02, // Text 109 CALLING_ANI = 0x03, // Text 110 CALLING_NAME = 0x04, // Text 111 CALLED_CONTEXT = 0x05, // Text 112 USERNAME = 0x06, // Text 113 PASSWORD = 0x07, // Text 114 CAPABILITY = 0x08, // DW 115 FORMAT = 0x09, // DW 116 LANGUAGE = 0x0a, // Text 117 VERSION = 0x0b, // W Value: IAX_PROTOCOL_VERSION 118 ADSICPE = 0x0c, // W 119 DNID = 0x0d, // Text 120 AUTHMETHODS = 0x0e, // W 121 CHALLENGE = 0x0f, // Text 122 MD5_RESULT = 0x10, // Text 123 RSA_RESULT = 0x11, // Text 124 APPARENT_ADDR = 0x12, // BIN 125 REFRESH = 0x13, // W 126 DPSTATUS = 0x14, // W 127 CALLNO = 0x15, // W Max value: IAX2_MAX_CALLNO 128 CAUSE = 0x16, // Text 129 IAX_UNKNOWN = 0x17, // B 130 MSGCOUNT = 0x18, // W 131 AUTOANSWER = 0x19, // Null 132 MUSICONHOLD = 0x1a, // Text 133 TRANSFERID = 0x1b, // DW 134 RDNIS = 0x1c, // Text 135 PROVISIONING = 0x1d, // BIN 136 AESPROVISIONING = 0x1e, // BIN 137 DATETIME = 0x1f, // DW 138 DEVICETYPE = 0x20, // Text 139 SERVICEIDENT = 0x21, // BIN 140 FIRMWAREVER = 0x22, // W 141 FWBLOCKDESC = 0x23, // DW 142 FWBLOCKDATA = 0x24, // BIN 143 PROVVER = 0x25, // DW 144 CALLINGPRES = 0x26, // B 145 CALLINGTON = 0x27, // B 146 CALLINGTNS = 0x28, // W 147 SAMPLINGRATE = 0x29, // DW 148 CAUSECODE = 0x2a, // B 149 ENCRYPTION = 0x2b, // B 150 ENKEY = 0x2c, // BIN 151 CODEC_PREFS = 0x2d, // Text 152 RR_JITTER = 0x2e, // DW 153 RR_LOSS = 0x2f, // DW 154 RR_PKTS = 0x30, // DW 155 RR_DELAY = 0x31, // W 156 RR_DROPPED = 0x32, // DW 157 RR_OOO = 0x33, // DW 158 CALLTOKEN = 0x36, // BIN 159 CAPABILITY2 = 0x37, // BIN 1 byte version + array 160 FORMAT2 = 0x38, // BIN 1 byte version + array 161 }; 162 163 /** 164 * Constructor 165 * @param type Type of this IE 166 */ IAXInfoElement(Type type)167 inline IAXInfoElement(Type type) : m_type(type) {} 168 169 /** 170 * Destructor 171 */ ~IAXInfoElement()172 virtual ~IAXInfoElement() {} 173 174 /** 175 * Get the type of this IE 176 * @return Type of this IE 177 */ type()178 inline Type type() const 179 { return m_type; } 180 181 /** 182 * Constructs a buffer containing this Information Element 183 * @param buf Destination buffer 184 */ 185 virtual void toBuffer(DataBlock& buf); 186 187 /** 188 * Add this element to a string 189 * @param buf Destination string 190 */ 191 virtual void toString(String& buf); 192 193 /** 194 * Get the text associated with an IE type value 195 * @param ieCode Numeric code of the IE 196 * @return Pointer to the IE text or 0 if it doesn't exist 197 */ ieText(u_int8_t ieCode)198 static inline const char* ieText(u_int8_t ieCode) 199 { return lookup(ieCode,s_ieData); } 200 201 /** 202 * Retrieve the cause name associated with a given code 203 * @param code Cause code 204 * @return Cause name, 0 if not found 205 */ causeName(int code)206 static inline const char* causeName(int code) 207 { return lookup(code,s_causeName); } 208 209 /** 210 * Retrieve the cause code associated with a given name 211 * @param name Cause name 212 * @param defVal Default value to return if not found 213 * @return Cause code 214 */ 215 static inline int causeCode(const char* name, int defVal = 0) 216 { return lookup(name,s_causeName,defVal); } 217 218 /** 219 * Cause code dictionary 220 */ 221 static const TokenDict s_causeName[]; 222 223 /** 224 * Number type dictionary 225 */ 226 static const TokenDict s_typeOfNumber[]; 227 228 /** 229 * Number presentation dictionary 230 */ 231 static const TokenDict s_presentation[]; 232 233 /** 234 * Number screening dictionary 235 */ 236 static const TokenDict s_screening[]; 237 238 private: 239 static const TokenDict s_ieData[];// Association between IE type and text 240 Type m_type; // Type of this IE 241 }; 242 243 /** 244 * This class holds a single Information Element with text data 245 * @short A single IAX2 text Information Element 246 */ 247 class YIAX_API IAXInfoElementString : public IAXInfoElement 248 { 249 public: 250 /** 251 * Constructor 252 * @param type Type of this IE 253 * @param buf Source buffer to construct this IE 254 * @param len Buffer length 255 */ IAXInfoElementString(Type type,const char * buf,unsigned len)256 inline IAXInfoElementString(Type type, const char* buf, unsigned len) : IAXInfoElement(type), m_strData(buf,(int)len) 257 {} 258 259 /** 260 * Destructor 261 */ ~IAXInfoElementString()262 virtual ~IAXInfoElementString() {} 263 264 /** 265 * Get the data length 266 * @return The data length 267 */ length()268 inline int length() const 269 { return m_strData.length(); } 270 271 /** 272 * Get the data 273 * @return The data 274 */ data()275 inline String& data() 276 { return m_strData; } 277 278 /** 279 * Constructs a buffer containing this Information Element 280 * @param buf Destination buffer 281 */ 282 virtual void toBuffer(DataBlock& buf); 283 284 /** 285 * Add this element to a string 286 * @param buf Destination string 287 */ toString(String & buf)288 virtual void toString(String& buf) 289 { buf << m_strData; } 290 291 private: 292 String m_strData; // IE text data 293 }; 294 295 /** 296 * This class holds a single Information Element with 1, 2 or 4 byte(s) length data 297 * @short A single IAX2 numeric Information Element 298 */ 299 class YIAX_API IAXInfoElementNumeric : public IAXInfoElement 300 { 301 public: 302 /** 303 * Constructor 304 * @param type Type of this IE 305 * @param val Source value to construct this IE 306 * @param len Value length 307 */ 308 IAXInfoElementNumeric(Type type, u_int32_t val, u_int8_t len); 309 310 /** 311 * Destructor 312 */ ~IAXInfoElementNumeric()313 virtual ~IAXInfoElementNumeric() {} 314 315 /** 316 * Get the data length 317 * @return The data length 318 */ length()319 inline int length() const 320 { return m_length; } 321 322 /** 323 * Get the data 324 * @return The data 325 */ data()326 inline u_int32_t data() const 327 { return m_numericData; } 328 329 /** 330 * Constructs a buffer containing this Information Element 331 * @param buf Destination buffer 332 */ 333 virtual void toBuffer(DataBlock& buf); 334 335 /** 336 * Add this element to a string 337 * @param buf Destination string 338 */ 339 virtual void toString(String& buf); 340 341 private: 342 u_int8_t m_length; // IE data length 343 u_int32_t m_numericData; // IE numeric data 344 }; 345 346 /** 347 * This class holds a single Information Element with binary data 348 * @short A single IAX2 numeric Information Element 349 */ 350 class YIAX_API IAXInfoElementBinary : public IAXInfoElement 351 { 352 public: 353 /** 354 * Constructor 355 * @param type Type of this IE 356 * @param buf Source buffer to construct this IE 357 * @param len Buffer length 358 */ IAXInfoElementBinary(Type type,unsigned char * buf,unsigned len)359 IAXInfoElementBinary(Type type, unsigned char* buf, unsigned len) : IAXInfoElement(type), m_data(buf,len) 360 {} 361 362 /** 363 * Destructor 364 */ ~IAXInfoElementBinary()365 virtual ~IAXInfoElementBinary() {} 366 367 /** 368 * Get the data length 369 * @return The data length 370 */ length()371 inline int length() const 372 { return m_data.length(); } 373 374 /** 375 * Get the data 376 * @return The data 377 */ data()378 inline DataBlock& data() 379 { return m_data; } 380 381 /** 382 * Set the data 383 * @param buf Source buffer to construct this IE 384 * @param len Buffer length 385 */ setData(void * buf,unsigned len)386 inline void setData(void* buf, unsigned len) 387 { m_data.assign(buf,len); } 388 389 /** 390 * Constructs a buffer containing this Information Element 391 * @param buf Destination buffer 392 */ 393 virtual void toBuffer(DataBlock& buf); 394 395 /** 396 * Constructs an APPARENT_ADDR information element from a SocketAddr object 397 * @param addr Source object 398 * @return A valid IAXInfoElementBinary pointer 399 */ 400 static IAXInfoElementBinary* packIP(const SocketAddr& addr); 401 402 /** 403 * Decode an APPARENT_ADDR information element and copy it to a SocketAddr object 404 * @param addr Destination object 405 * @param ie Source IE 406 * @return False if ie is 0 407 */ 408 static bool unpackIP(SocketAddr& addr, IAXInfoElementBinary* ie); 409 410 /** 411 * Add this element to a string 412 * @param buf Destination string 413 */ 414 virtual void toString(String& buf); 415 416 private: 417 DataBlock m_data; // IE binary data 418 }; 419 420 /** 421 * Management class for a list of Information Elements 422 * @short Information Element container 423 */ 424 class YIAX_API IAXIEList 425 { 426 public: 427 /** 428 * Constructor 429 */ 430 IAXIEList(); 431 432 /** 433 * Constructor. Construct the list from an IAXFullFrame object 434 * @param frame Source object 435 * @param incoming True if it is an incoming frame 436 */ 437 IAXIEList(const IAXFullFrame* frame, bool incoming = true); 438 439 /** 440 * Destructor 441 */ 442 ~IAXIEList(); 443 444 /** 445 * Get the invalid IE list flag 446 * @return False if the last frame parse was unsuccessful 447 */ invalidIEList()448 inline bool invalidIEList() const 449 { return m_invalidIEList; } 450 451 /** 452 * Clear the list 453 */ clear()454 inline void clear() 455 { m_list.clear(); } 456 457 /** 458 * Check if the list is empty 459 * @return True if the list is empty 460 */ empty()461 inline bool empty() 462 { return 0 == m_list.skipNull(); } 463 464 /** 465 * Insert a VERSION Information Element in the list if not already done 466 */ 467 void insertVersion(); 468 469 /** 470 * Get the validity of the VERSION Information Element of the list if any 471 * @return False if version is not IAX_PROTOCOL_VERSION or the list doesn't contain a VERSION Information Element 472 */ validVersion()473 inline bool validVersion() { 474 u_int32_t ver = 0xFFFF; 475 getNumeric(IAXInfoElement::VERSION,ver); 476 return ver == IAX_PROTOCOL_VERSION; 477 } 478 479 /** 480 * Append an Information Element to the list 481 * @param ie IAXInfoElement pointer to append 482 */ appendIE(IAXInfoElement * ie)483 inline void appendIE(IAXInfoElement* ie) 484 { m_list.append(ie); } 485 486 /** 487 * Append an Information Element taken from another list 488 * @param src Source IE list 489 * @param type IE to move 490 * @return True if found and added 491 */ appendIE(IAXIEList & src,IAXInfoElement::Type type)492 inline bool appendIE(IAXIEList& src, IAXInfoElement::Type type) { 493 IAXInfoElement* ie = src.getIE(type,true); 494 if (ie) 495 appendIE(ie); 496 return ie != 0; 497 } 498 499 /** 500 * Append an Information Element to the list 501 * @param type The type of the IAXInfoElement to append 502 */ appendNull(IAXInfoElement::Type type)503 inline void appendNull(IAXInfoElement::Type type) 504 { m_list.append(new IAXInfoElement(type)); } 505 506 /** 507 * Append a text Information Element to the list from a String 508 * @param type The type of the IAXInfoElementString to append 509 * @param src The source 510 */ appendString(IAXInfoElement::Type type,const String & src)511 inline void appendString(IAXInfoElement::Type type, const String& src) 512 { m_list.append(new IAXInfoElementString(type,src.c_str(),src.length())); } 513 514 /** 515 * Append a text Information Element to the list from a buffer 516 * @param type The type of the IAXInfoElementString to append 517 * @param src The source 518 * @param len Source length 519 */ appendString(IAXInfoElement::Type type,unsigned char * src,unsigned len)520 inline void appendString(IAXInfoElement::Type type, unsigned char* src, unsigned len) 521 { m_list.append(new IAXInfoElementString(type,(char*)src,len)); } 522 523 /** 524 * Append a numeric Information Element to the list 525 * @param type The type of the IAXInfoElementNumeric to append 526 * @param value The source 527 * @param len Source length 528 */ appendNumeric(IAXInfoElement::Type type,u_int32_t value,u_int8_t len)529 inline void appendNumeric(IAXInfoElement::Type type, u_int32_t value, u_int8_t len) 530 { m_list.append(new IAXInfoElementNumeric(type,value,len)); } 531 532 /** 533 * Append a binary Information Element to the list 534 * @param type The type of the IAXInfoElementBinary to append 535 * @param data The source data to append 536 * @param len Source length 537 */ appendBinary(IAXInfoElement::Type type,unsigned char * data,unsigned len)538 inline void appendBinary(IAXInfoElement::Type type, unsigned char* data, unsigned len) 539 { m_list.append(new IAXInfoElementBinary(type,data,len)); } 540 541 /** 542 * Construct the list from an IAXFullFrame object. 543 * On exit m_invalidIEList will contain the opposite of the returned value 544 * @param frame Source object 545 * @param incoming True if it is an incoming frame 546 * @return False if the frame contains invalid IEs 547 */ 548 bool createFromFrame(const IAXFullFrame* frame, bool incoming = true); 549 550 /** 551 * Construct a buffer from this list 552 * @param buf Destination buffer 553 */ 554 void toBuffer(DataBlock& buf); 555 556 /** 557 * Add this list to a string 558 * @param dest Destination string 559 * @param indent Optional indent for each element 560 */ 561 void toString(String& dest, const char* indent = 0); 562 563 /** 564 * Retrieve an IAXInfoElement from the list 565 * @param type The desired type 566 * @param remove True to remove from list. The caller will own the object 567 * @return An IAXInfoElement pointer or 0 if the list doesn't contain an IE of this type 568 */ 569 IAXInfoElement* getIE(IAXInfoElement::Type type, bool remove = false); 570 571 /** 572 * Get the data of a list item into a String. Before any operation dest is cleared 573 * @param type The desired type 574 * @param dest The destination String 575 * @return False if the list doesn't contain an IE of this type 576 */ 577 bool getString(IAXInfoElement::Type type, String& dest); 578 579 /** 580 * Get the data of a list item into a numeric destination 581 * @param type The desired type 582 * @param dest The destination 583 * @return False if the list doesn't contain an IE of this type 584 */ 585 bool getNumeric(IAXInfoElement::Type type, u_int32_t& dest); 586 587 /** 588 * Get the data of a list item into a DataBlock. Before any operation dest is cleared 589 * @param type The desired type 590 * @param dest The destination buffer 591 * @return False if the list doesn't contain an IE of this type 592 */ 593 bool getBinary(IAXInfoElement::Type type, DataBlock& dest); 594 595 private: 596 bool m_invalidIEList; // Invalid IE flag 597 ObjList m_list; // The IE list 598 }; 599 600 /** 601 * This class holds the enumeration values for authentication methods 602 * @short Wrapper class for authentication methods values 603 */ 604 class YIAX_API IAXAuthMethod 605 { 606 public: 607 /** 608 * Authentication method enumeration types 609 */ 610 enum Type { 611 Text = 1, 612 MD5 = 2, 613 RSA = 4, 614 }; 615 616 /** 617 * Create a string list from authentication methods 618 * @param dest The destination 619 * @param auth The authentication methods as ORed bits 620 * @param sep The separator to use 621 */ 622 static void authList(String& dest, u_int16_t auth, char sep); 623 624 static TokenDict s_texts[]; 625 }; 626 627 628 /** 629 * This class holds IAX format description 630 * @short IAX format description 631 */ 632 class YIAX_API IAXFormatDesc 633 { 634 public: 635 /** 636 * Constructor 637 */ IAXFormatDesc()638 inline IAXFormatDesc() 639 : m_format(0), m_multiplier(1) 640 {} 641 642 /** 643 * Get the format 644 * @return The format 645 */ format()646 inline u_int32_t format() const 647 { return m_format; } 648 649 /** 650 * Get the format multiplier used to translate timestamps 651 * @return The format multiplier (always greater then 0) 652 */ multiplier()653 inline unsigned int multiplier() const 654 { return m_multiplier; } 655 656 /** 657 * Set the format 658 * @param fmt The format 659 * @param type Format type as IAXFormat::Media enumeration 660 */ 661 void setFormat(u_int32_t fmt, int type); 662 663 protected: 664 u_int32_t m_format; // The format 665 unsigned int m_multiplier; // Format multiplier derived from sampling rate 666 }; 667 668 /** 669 * This class holds the enumeration values for audio and video formats 670 * @short Wrapper class for audio and video formats 671 */ 672 class YIAX_API IAXFormat 673 { 674 public: 675 /** 676 * Format enumeration types 677 */ 678 enum Formats { 679 G723_1 = (1 << 0), 680 GSM = (1 << 1), 681 ULAW = (1 << 2), 682 ALAW = (1 << 3), 683 G726 = (1 << 4), 684 ADPCM = (1 << 5), 685 SLIN = (1 << 6), 686 LPC10 = (1 << 7), 687 G729 = (1 << 8), 688 SPEEX = (1 << 9), 689 ILBC = (1 << 10), 690 G726AAL2 = (1 << 11), 691 G722 = (1 << 12), 692 AMR = (1 << 13), 693 // NOTE: GSM Half Rate is not defined in RFC5456 694 GSM_HR = (1 << 31), 695 AudioMask = G723_1 | GSM | ULAW | ALAW | G726 | ADPCM | SLIN | LPC10 | G729 | SPEEX | 696 ILBC | G726AAL2 | G722 | AMR | GSM_HR, 697 JPEG = (1 << 16), 698 PNG = (1 << 17), 699 ImageMask = JPEG | PNG, 700 H261 = (1 << 18), 701 H263 = (1 << 19), 702 H263p = (1 << 20), 703 H264 = (1 << 21), 704 VideoMask = H261 | H263 | H263p | H264, 705 }; 706 707 /** 708 * Media type enumeration 709 */ 710 enum Media { 711 Audio = 0, 712 Video, 713 Image, 714 TypeCount 715 }; 716 717 /** 718 * Constructor. Build an audio format 719 * @param type Media type 720 */ 721 inline IAXFormat(int type = Audio) m_type(type)722 : m_type(type) 723 {} 724 725 /** 726 * Get the media type 727 * @return Media type 728 */ type()729 inline int type() const 730 { return m_type; } 731 732 /** 733 * Get the format 734 * @return The format 735 */ format()736 inline u_int32_t format() const 737 { return m_format.format(); } 738 739 /** 740 * Get the incoming format 741 * @return The incoming format 742 */ in()743 inline u_int32_t in() const 744 { return m_formatIn.format(); } 745 746 /** 747 * Get the outgoing format 748 * @return The outgoing format 749 */ out()750 inline u_int32_t out() const 751 { return m_formatOut.format(); } 752 753 /** 754 * Get the incoming or outgoing format description 755 * @param in True to retrieve the incoming format, false to retrieve the outgoing one 756 * @return Requested format desc 757 */ formatDesc(bool in)758 inline const IAXFormatDesc& formatDesc(bool in) const 759 { return in ? m_formatIn : m_formatOut; } 760 761 /** 762 * Get the text associated with the format 763 * @return Format name 764 */ formatName()765 inline const char* formatName() const 766 { return formatName(format()); } 767 768 /** 769 * Get the text associated with the media type 770 * @return Media name 771 */ typeName()772 inline const char* typeName() const 773 { return typeName(m_type); } 774 775 /** 776 * Set format 777 * @param fmt Optional pointer to format to set 778 * @param fmtIn Optional pointer to incoming format to set 779 * @param fmtOut Optional pointer to outgoing format to set 780 */ 781 void set(u_int32_t* fmt, u_int32_t* fmtIn, u_int32_t* fmtOut); 782 783 /** 784 * Create a string list from formats 785 * @param dest The destination 786 * @param formats The formats 787 * @param dict Optional dictionary to use, 0 to use s_formats 788 * @param sep The separator to use 789 */ 790 static void formatList(String& dest, u_int32_t formats, const TokenDict* dict = 0, 791 const char* sep = ","); 792 793 /** 794 * Pick a format from a list of capabilities 795 * @param formats Capabilities list 796 * @param format Optional format to pick 797 * @return IAX format, 0 if not found 798 */ 799 static u_int32_t pickFormat(u_int32_t formats, u_int32_t format = 0); 800 801 /** 802 * Encode a formats list 803 * @param formats Formats list 804 * @param dict Dictionary to use 805 * @param sep Formats list separator 806 * @return Encoded formats 807 */ 808 static u_int32_t encode(const String& formats, const TokenDict* dict, char sep = ','); 809 810 /** 811 * Mask formats by type 812 * @param value Input format(s) 813 * @param type Media type to retrieve 814 * @return Media format(s) from input 815 */ mask(u_int32_t value,int type)816 static inline u_int32_t mask(u_int32_t value, int type) { 817 if (type == Audio) 818 return value & AudioMask; 819 if (type == Video) 820 return value & VideoMask; 821 if (type == Image) 822 return value & ImageMask; 823 return 0; 824 } 825 826 /** 827 * Clear formats by type 828 * @param value Input format(s) 829 * @param type Media type to clear 830 * @return Cleared format(s) from input 831 */ clear(u_int32_t value,int type)832 static inline u_int32_t clear(u_int32_t value, int type) { 833 if (type == Audio) 834 return value & ~AudioMask; 835 if (type == Video) 836 return value & ~VideoMask; 837 if (type == Image) 838 return value & ~ImageMask; 839 return value; 840 } 841 842 /** 843 * Get the text associated with a format 844 * @param fmt The desired format 845 * @return A pointer to the text associated with the format or 0 if the format doesn't exist 846 */ formatName(u_int32_t fmt)847 static inline const char* formatName(u_int32_t fmt) 848 { return lookup(fmt,s_formats); } 849 850 /** 851 * Get the text associated with a media type 852 * @param type The media type 853 * @return A pointer to the text associated with the media type 854 */ typeName(int type)855 static inline const char* typeName(int type) 856 { return lookup(type,s_types); } 857 858 /** 859 * Get the text associated with a media type 860 * @param type The media type 861 * @return A string associated with the media type 862 */ typeNameStr(int type)863 static inline const String& typeNameStr(int type) 864 { return s_typesList[type]; } 865 866 /** 867 * Keep the texts associated with the formats 868 */ 869 static const TokenDict s_formats[]; 870 871 /** 872 * Keep the texts associated with type 873 */ 874 static const TokenDict s_types[]; 875 876 /** 877 * Keep the texts associated with a type also as String 878 */ 879 static const String s_typesList[TypeCount]; 880 881 protected: 882 int m_type; 883 IAXFormatDesc m_format; 884 IAXFormatDesc m_formatIn; 885 IAXFormatDesc m_formatOut; 886 }; 887 888 /** 889 * This class holds the enumeration values for IAX control (subclass) 890 * @short Wrapper class for subclasses of frames of type IAX 891 */ 892 class YIAX_API IAXControl 893 { 894 public: 895 /** 896 * IAX control (subclass) enumeration types 897 */ 898 enum Type { 899 New = 0x01, 900 Ping = 0x02, 901 Pong = 0x03, 902 Ack = 0x04, 903 Hangup = 0x05, 904 Reject = 0x06, 905 Accept = 0x07, 906 AuthReq = 0x08, 907 AuthRep = 0x09, 908 Inval = 0x0a, 909 LagRq = 0x0b, 910 LagRp = 0x0c, 911 RegReq = 0x0d, 912 RegAuth = 0x0e, 913 RegAck = 0x0f, 914 RegRej = 0x10, 915 RegRel = 0x11, 916 VNAK = 0x12, 917 DpReq = 0x13, 918 DpRep = 0x14, 919 Dial = 0x15, 920 TxReq = 0x16, 921 TxCnt = 0x17, 922 TxAcc = 0x18, 923 TxReady = 0x19, 924 TxRel = 0x1a, 925 TxRej = 0x1b, 926 Quelch = 0x1c, 927 Unquelch = 0x1d, 928 Poke = 0x1e, 929 //Reserved = 0x1f, 930 MWI = 0x20, 931 Unsupport = 0x21, 932 Transfer = 0x22, 933 Provision = 0x23, 934 FwDownl = 0x24, 935 FwData = 0x25, 936 CallToken = 0x28, 937 }; 938 939 /** 940 * Get the string associated with the given IAX control type 941 * @param type The requested type 942 * @return The text if type is valid or 0 943 */ typeText(int type)944 static inline const char* typeText(int type) 945 { return lookup(type,s_types,0); } 946 947 private: 948 static TokenDict s_types[]; // Keep the association between IAX control codes and their name 949 }; 950 951 /** 952 * This class holds all data needded to manage an IAX frame 953 * @short This class holds an IAX frame 954 */ 955 class YIAX_API IAXFrame : public RefObject 956 { 957 public: 958 /** 959 * IAX frame type enumeration 960 */ 961 enum Type { 962 DTMF = 0x01, 963 Voice = 0x02, 964 Video = 0x03, 965 Control = 0x04, 966 Null = 0x05, 967 IAX = 0x06, 968 Text = 0x07, 969 Image = 0x08, 970 HTML = 0x09, 971 Noise = 0x0a, 972 }; 973 974 /** 975 * Constructor. Constructs an incoming frame 976 * @param type Frame type 977 * @param sCallNo Source call number 978 * @param tStamp Frame timestamp 979 * @param retrans Retransmission flag 980 * @param buf IE buffer 981 * @param len IE buffer length 982 * @param mark Mark flag 983 */ 984 IAXFrame(Type type, u_int16_t sCallNo, u_int32_t tStamp, bool retrans, 985 const unsigned char* buf, unsigned int len, bool mark = false); 986 987 /** 988 * Destructor 989 */ 990 virtual ~IAXFrame(); 991 992 /** 993 * Get the type of this frame as enumeration 994 * @return The type of this frame as enumeration 995 */ type()996 inline Type type() const 997 { return m_type; } 998 999 /** 1000 * Get the data buffer of the frame 1001 * @return The data buffer of the frame 1002 */ data()1003 inline DataBlock& data() 1004 { return m_data; } 1005 1006 /** 1007 * Get the retransmission flag of this frame 1008 * @return The retransmission flag of this frame 1009 */ retrans()1010 inline bool retrans() const 1011 { return m_retrans; } 1012 1013 /** 1014 * Get the source call number of this frame 1015 * @return The source call number of this frame 1016 */ sourceCallNo()1017 inline u_int16_t sourceCallNo() const 1018 { return m_sCallNo; } 1019 1020 /** 1021 * Get the timestamp of this frame 1022 * @return The timestamp of this frame 1023 */ timeStamp()1024 inline u_int32_t timeStamp() const 1025 { return m_tStamp; } 1026 1027 /** 1028 * Get the mark flag 1029 * @return The mark flag 1030 */ mark()1031 inline bool mark() const 1032 { return m_mark; } 1033 1034 /** 1035 * Get a pointer to this frame if it is a full frame 1036 * @return A pointer to this frame if it is a full frame or 0 1037 */ 1038 virtual IAXFullFrame* fullFrame(); 1039 1040 /** 1041 * Parse a received buffer and returns a IAXFrame pointer if valid 1042 * @param buf Received buffer 1043 * @param len Buffer length 1044 * @param engine The IAXEngine who requested the operation 1045 * @param addr The source address 1046 * @return A frame pointer on success or 0 1047 */ 1048 static IAXFrame* parse(const unsigned char* buf, unsigned int len, IAXEngine* engine = 0, const SocketAddr* addr = 0); 1049 1050 /** 1051 * Build a miniframe buffer 1052 * @param dest Destination buffer 1053 * @param sCallNo Source call number 1054 * @param ts Frame timestamp 1055 * @param data Data 1056 * @param len Data length 1057 */ buildMiniFrame(DataBlock & dest,u_int16_t sCallNo,u_int32_t ts,void * data,unsigned int len)1058 static inline void buildMiniFrame(DataBlock& dest, u_int16_t sCallNo, u_int32_t ts, 1059 void* data, unsigned int len) { 1060 unsigned char header[4] = {(unsigned char)(sCallNo >> 8), 1061 (unsigned char)sCallNo,(unsigned char)(ts >> 8),(unsigned char)ts}; 1062 dest.assign(header,4); 1063 dest.append(data,len); 1064 } 1065 1066 /** 1067 * Build a video meta frame buffer 1068 * @param dest Destination buffer 1069 * @param sCallNo Source call number 1070 * @param tStamp Frame timestamp 1071 * @param mark Frame mark 1072 * @param data Data 1073 * @param len Data length 1074 */ 1075 static void buildVideoMetaFrame(DataBlock& dest, u_int16_t sCallNo, u_int32_t tStamp, 1076 bool mark, void* data, unsigned int len); 1077 1078 /** 1079 * Pack a subclass value according to IAX protocol 1080 * @param value Value to pack 1081 * @return The packed subclass value or 0 if invalid (>255 and not a power of 2) 1082 */ 1083 static u_int8_t packSubclass(u_int32_t value); 1084 1085 /** 1086 * Unpack a subclass value according to IAX protocol 1087 * @param value Value to unpack 1088 * @return The unpacked subclass value 1089 */ 1090 static u_int32_t unpackSubclass(u_int8_t value); 1091 1092 /** 1093 * Get the string associated with the given IAX frame type 1094 * @param type The requested type 1095 * @return The text if type is valid or 0 1096 */ typeText(int type)1097 static inline const char* typeText(int type) 1098 { return lookup(type,s_types,0); } 1099 1100 protected: 1101 /** 1102 * Contains the frame's IE list for an incoming frame or the whole frame for an outgoing one 1103 */ 1104 DataBlock m_data; 1105 1106 /** 1107 * Retransmission flag 1108 */ 1109 bool m_retrans; 1110 1111 private: 1112 static TokenDict s_types[]; // Keep the association between IAX frame types and their names 1113 Type m_type; // Frame type 1114 u_int16_t m_sCallNo; // Source call number 1115 u_int32_t m_tStamp; // Frame timestamp 1116 bool m_mark; // Mark flag 1117 }; 1118 1119 /** 1120 * This class holds all data needded to manage an IAX full frame 1121 * @short This class holds an IAX full frame 1122 */ 1123 class YIAX_API IAXFullFrame : public IAXFrame 1124 { 1125 public: 1126 /** 1127 * IAX frame subclass enumeration types for frames of type Control 1128 */ 1129 enum ControlType { 1130 Hangup = 0x01, 1131 //Ring = 0x02, 1132 Ringing = 0x03, 1133 Answer = 0x04, 1134 Busy = 0x05, 1135 Congestion = 0x08, 1136 FlashHook = 0x09, 1137 Option = 0x0b, 1138 KeyRadio = 0x0c, 1139 UnkeyRadio = 0x0d, 1140 Progressing = 0x0e, 1141 Proceeding = 0x0f, 1142 Hold = 0x10, 1143 Unhold = 0x11, 1144 VidUpdate = 0x12, 1145 SrcUpdate = 0x14, 1146 StopSounds = 0xff, 1147 }; 1148 1149 /** 1150 * Constructor. Constructs an incoming full frame 1151 * @param type Frame type 1152 * @param subclass Frame subclass 1153 * @param sCallNo Source (remote) call number 1154 * @param dCallNo Destination (local) call number 1155 * @param oSeqNo Outgoing sequence number 1156 * @param iSeqNo Incoming (expected) sequence number 1157 * @param tStamp Frame timestamp 1158 * @param retrans Retransmission flag 1159 * @param buf IE buffer 1160 * @param len IE buffer length 1161 * @param mark Mark flag 1162 */ 1163 IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 1164 unsigned char oSeqNo, unsigned char iSeqNo, 1165 u_int32_t tStamp, bool retrans, 1166 const unsigned char* buf, unsigned int len, bool mark = false); 1167 1168 /** 1169 * Constructor. Constructs an outgoing full frame 1170 * @param type Frame type 1171 * @param subclass Frame subclass 1172 * @param sCallNo Source (remote) call number 1173 * @param dCallNo Destination (local) call number 1174 * @param oSeqNo Outgoing sequence number 1175 * @param iSeqNo Incoming (expected) sequence number 1176 * @param tStamp Frame timestamp 1177 * @param buf IE buffer 1178 * @param len IE buffer length 1179 * @param mark Mark flag 1180 */ 1181 IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 1182 unsigned char oSeqNo, unsigned char iSeqNo, 1183 u_int32_t tStamp, 1184 const unsigned char* buf = 0, unsigned int len = 0, bool mark = false); 1185 1186 /** 1187 * Constructor. Constructs an outgoing full frame 1188 * @param type Frame type 1189 * @param subclass Frame subclass 1190 * @param sCallNo Source (remote) call number 1191 * @param dCallNo Destination (local) call number 1192 * @param oSeqNo Outgoing sequence number 1193 * @param iSeqNo Incoming (expected) sequence number 1194 * @param tStamp Frame timestamp 1195 * @param ieList List of frame IEs 1196 * @param maxlen Max frame data length 1197 * @param mark Mark flag 1198 */ 1199 IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 1200 unsigned char oSeqNo, unsigned char iSeqNo, 1201 u_int32_t tStamp, IAXIEList* ieList, u_int16_t maxlen, bool mark = false); 1202 1203 /** 1204 * Destructor 1205 */ 1206 virtual ~IAXFullFrame(); 1207 1208 /** 1209 * Get the destination call number 1210 * @return The destination call number 1211 */ destCallNo()1212 inline u_int16_t destCallNo() const 1213 { return m_dCallNo; } 1214 1215 /** 1216 * Get the outgoing sequence number 1217 * @return The outgoing sequence number 1218 */ oSeqNo()1219 inline unsigned char oSeqNo() const 1220 { return m_oSeqNo; } 1221 1222 /** 1223 * Get the incoming sequence number 1224 * @return The incoming sequence number 1225 */ iSeqNo()1226 inline unsigned char iSeqNo() const 1227 { return m_iSeqNo; } 1228 1229 /** 1230 * Get the subclass of this frame 1231 * @return The subclass of this frame 1232 */ subclass()1233 inline u_int32_t subclass() const 1234 { return m_subclass; } 1235 1236 /** 1237 * Check if this frame is used to request authentication 1238 * @return True if this frame is used to request authentication (like RegReq or RegAuth) 1239 */ isAuthReq()1240 inline bool isAuthReq() const { 1241 return type() == IAXFrame::IAX && 1242 (subclass() == IAXControl::AuthReq || subclass() == IAXControl::RegAuth); 1243 } 1244 1245 /** 1246 * Check if this frame is an INVAL one 1247 * @return True if this frame is INVAL 1248 */ isInval()1249 inline bool isInval() const 1250 { return type() == IAXFrame::IAX && subclass() == IAXControl::Inval; } 1251 1252 /** 1253 * Get a pointer to this frame if it is a full frame 1254 * @return A pointer to this frame 1255 */ 1256 virtual IAXFullFrame* fullFrame(); 1257 1258 /** 1259 * Rebuild frame buffer from the list of IEs 1260 * @param maxlen Max frame data length 1261 */ 1262 void updateBuffer(u_int16_t maxlen); 1263 1264 /** 1265 * Retrieve the IE list 1266 * @return IAXIEList pointer or NULL 1267 */ ieList()1268 inline IAXIEList* ieList() 1269 { return m_ieList; } 1270 1271 /** 1272 * Update IE list from buffer if not already done 1273 * @param incoming True if this is an incoming frame 1274 * @return True if the list is valid 1275 */ 1276 bool updateIEList(bool incoming); 1277 1278 /** 1279 * Remove the IE list 1280 * @param delObj True to delete it 1281 * @return IAXIEList pointer or NULL if requested to delete it or already NULL 1282 */ 1283 IAXIEList* removeIEList(bool delObj = true); 1284 1285 /** 1286 * Fill a string with this frame 1287 * @param dest The string to fill 1288 * @param local The local address 1289 * @param remote The remote address 1290 * @param incoming True if it is an incoming frame 1291 */ 1292 void toString(String& dest, const SocketAddr& local, const SocketAddr& remote, 1293 bool incoming); 1294 1295 /** 1296 * Get the string associated with the given IAX control type 1297 * @param type The requested control type 1298 * @return The text if type is valid or 0 1299 */ controlTypeText(int type)1300 static inline const char* controlTypeText(int type) 1301 { return lookup(type,s_controlTypes,0); } 1302 1303 protected: 1304 /** 1305 * Destroyed notification. Clear data 1306 */ 1307 virtual void destroyed(); 1308 1309 private: 1310 // Build frame buffer header 1311 void setDataHeader(); 1312 static TokenDict s_controlTypes[]; // Keep the association between control types and their names 1313 u_int16_t m_dCallNo; // Destination call number 1314 unsigned char m_oSeqNo; // Out sequence number 1315 unsigned char m_iSeqNo; // In sequence number 1316 u_int32_t m_subclass; // Subclass 1317 IAXIEList* m_ieList; // List of IEs 1318 }; 1319 1320 /** 1321 * This class holds all data needded to manage an outgoing IAX full frame 1322 * @short This class holds an outgoing IAX full frame 1323 */ 1324 class YIAX_API IAXFrameOut : public IAXFullFrame 1325 { 1326 public: 1327 /** 1328 * Constructor. Constructs an outgoing full frame 1329 * @param type Frame type 1330 * @param subclass Frame subclass 1331 * @param sCallNo Source (remote) call number 1332 * @param dCallNo Destination (local) call number 1333 * @param oSeqNo Outgoing sequence number 1334 * @param iSeqNo Incoming (expected) sequence number 1335 * @param tStamp Frame timestamp 1336 * @param buf IE buffer 1337 * @param len IE buffer length 1338 * @param retransCount Retransmission counter 1339 * @param retransIntervalMs Time interval to the next retransmission 1340 * @param ackOnly Acknoledge only flag. If true, the frame only expects an ACK 1341 * @param mark Mark flag 1342 */ 1343 inline IAXFrameOut(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 1344 unsigned char oSeqNo, unsigned char iSeqNo, u_int32_t tStamp, 1345 const unsigned char* buf, unsigned int len, 1346 u_int16_t retransCount, u_int32_t retransIntervalMs, 1347 bool ackOnly, bool mark = false) IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,buf,len,mark)1348 : IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,buf,len,mark), 1349 m_ack(false), m_ackOnly(ackOnly), m_retransCount(retransCount), 1350 m_retransTimeInterval(retransIntervalMs * 1000), 1351 m_nextTransTime(Time::now() + m_retransTimeInterval) 1352 {} 1353 1354 /** 1355 * Constructor. Constructs an outgoing full frame 1356 * @param type Frame type 1357 * @param subclass Frame subclass 1358 * @param sCallNo Source (remote) call number 1359 * @param dCallNo Destination (local) call number 1360 * @param oSeqNo Outgoing sequence number 1361 * @param iSeqNo Incoming (expected) sequence number 1362 * @param tStamp Frame timestamp 1363 * @param ieList List of frame IEs 1364 * @param maxlen Max frame data length 1365 * @param retransCount Retransmission counter 1366 * @param retransIntervalMs Time interval to the next retransmission 1367 * @param ackOnly Acknoledge only flag. If true, the frame only expects an ACK 1368 * @param mark Mark flag 1369 */ 1370 inline IAXFrameOut(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 1371 unsigned char oSeqNo, unsigned char iSeqNo, u_int32_t tStamp, 1372 IAXIEList* ieList, u_int16_t maxlen, 1373 u_int16_t retransCount, u_int32_t retransIntervalMs, bool ackOnly, 1374 bool mark = false) IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,ieList,maxlen,mark)1375 : IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,ieList,maxlen,mark), 1376 m_ack(false), m_ackOnly(ackOnly), m_retransCount(retransCount), 1377 m_retransTimeInterval(retransIntervalMs * 1000), 1378 m_nextTransTime(Time::now() + m_retransTimeInterval) 1379 {} 1380 1381 /** 1382 * Destructor 1383 */ ~IAXFrameOut()1384 virtual ~IAXFrameOut() 1385 {} 1386 1387 /** 1388 * Get the retransmission counter of this frame 1389 * @return The retransmission counter is 0 1390 */ retransCount()1391 inline unsigned int retransCount() const 1392 { return m_retransCount; } 1393 1394 /** 1395 * Ask the frame if it's time for retransmit 1396 * @param time Current time 1397 * @return True if it's time to retransmit 1398 */ timeForRetrans(u_int64_t time)1399 inline bool timeForRetrans(u_int64_t time) const 1400 { return time >= m_nextTransTime; } 1401 1402 /** 1403 * Set the retransmission flag of this frame 1404 */ setRetrans()1405 inline void setRetrans() { 1406 if (m_retrans) 1407 return; 1408 m_retrans = true; 1409 ((unsigned char*)m_data.data())[2] |= 0x80; 1410 } 1411 1412 /** 1413 * Update the retransmission counter and the time to next retransmission 1414 */ transmitted()1415 inline void transmitted() { 1416 if (!m_retransCount) 1417 return; 1418 m_retransCount--; 1419 m_retransTimeInterval *= 2; 1420 m_nextTransTime += m_retransTimeInterval; 1421 } 1422 1423 /** 1424 * Get the acknoledged flag of this frame 1425 * @return The acknoledged flag of this frame 1426 */ ack()1427 inline bool ack() const 1428 { return m_ack; } 1429 1430 /** 1431 * Set the acknoledged flag of this frame 1432 */ setAck()1433 inline void setAck() 1434 { m_ack = true; } 1435 1436 /** 1437 * Get the acknoledge only flag of this frame 1438 * @return The acknoledge only flag of this frame 1439 */ ackOnly()1440 inline bool ackOnly() const 1441 { return m_ackOnly; } 1442 1443 /** 1444 * Check if absolute timeout can be set 1445 * @return True if absolute timeout can be set 1446 */ canSetTimeout()1447 inline bool canSetTimeout() 1448 { return m_retransTimeInterval != 0; } 1449 1450 /** 1451 * Set absolute timeout. Reset retransmission counter 1452 * @param tout Timeout time 1453 */ setTimeout(u_int64_t tout)1454 inline void setTimeout(u_int64_t tout) { 1455 if (!m_retransTimeInterval) 1456 return; 1457 m_retransTimeInterval = 0; 1458 m_retransCount = 0; 1459 m_nextTransTime = tout; 1460 } 1461 1462 private: 1463 bool m_ack; // Acknoledge flag 1464 bool m_ackOnly; // Frame need only ACK as a response 1465 u_int16_t m_retransCount; // Retransmission counter 1466 u_int32_t m_retransTimeInterval; // Retransmission interval 1467 u_int64_t m_nextTransTime; // Next transmission time 1468 }; 1469 1470 /** 1471 * This class holds trunk description 1472 * @short Trunk info 1473 */ 1474 class YIAX_API IAXTrunkInfo : public RefObject 1475 { 1476 public: 1477 /** 1478 * Constructor 1479 */ IAXTrunkInfo()1480 inline IAXTrunkInfo() 1481 : m_timestamps(true), m_sendInterval(IAX2_TRUNKFRAME_SEND_DEF), 1482 m_maxLen(IAX2_TRUNKFRAME_LEN_DEF), 1483 m_efficientUse(false), m_trunkInSyncUsingTs(true), 1484 m_trunkInTsDiffRestart(5000), 1485 m_retransCount(IAX2_RETRANS_COUNT_DEF), 1486 m_retransInterval(IAX2_RETRANS_INTERVAL_DEF), 1487 m_pingInterval(IAX2_PING_INTERVAL_DEF) 1488 {} 1489 1490 /** 1491 * Init non trunking related data 1492 * @param params Parameter list 1493 * @param prefix Parameter prefix 1494 * @param def Optional defaults 1495 */ 1496 void init(const NamedList& params, const String& prefix = String::empty(), 1497 const IAXTrunkInfo* def = 0); 1498 1499 /** 1500 * Init trunking from parameters 1501 * @param params Parameter list 1502 * @param prefix Parameter prefix 1503 * @param def Optional defaults 1504 * @param out True to init outgoing trunk data 1505 * @param in True to init incoming trunk data 1506 */ 1507 void initTrunking(const NamedList& params, const String& prefix = String::empty(), 1508 const IAXTrunkInfo* def = 0, bool out = true, bool in = true); 1509 1510 /** 1511 * Update trunking from parameters. Don't change values not present in list 1512 * @param params Parameter list 1513 * @param prefix Parameter prefix 1514 * @param out True to update outgoing trunk data 1515 * @param in True to update incoming trunk data 1516 */ 1517 void updateTrunking(const NamedList& params, const String& prefix = String::empty(), 1518 bool out = true, bool in = true); 1519 1520 /** 1521 * Dump info 1522 * @param buf Destination buffer 1523 * @param sep Parameters separator 1524 * @param out True to dump outgoing trunking info 1525 * @param in True to dump incoming trunking info 1526 * @param other True to dump non trunking info 1527 */ 1528 void dump(String& buf, const char* sep = " ", bool out = true, bool in = true, 1529 bool other = true); 1530 1531 bool m_timestamps; // Trunk type: with(out) timestamps 1532 unsigned int m_sendInterval; // Send interval 1533 unsigned int m_maxLen; // Max frame length 1534 bool m_efficientUse; // Outgoing trunking: use or not the trunk based on calls using it 1535 bool m_trunkInSyncUsingTs; // Incoming trunk without timestamps: use trunk 1536 // time or trunk timestamp to re-build frame ts 1537 u_int32_t m_trunkInTsDiffRestart; // Incoming trunk without timestamp: diff between 1538 // timestamps at which we restart 1539 unsigned int m_retransCount; // Frame retransmission counter 1540 unsigned int m_retransInterval; // Frame retransmission interval in milliseconds 1541 unsigned int m_pingInterval; // Ping interval in milliseconds 1542 }; 1543 1544 /** 1545 * Handle meta trunk frame with timestamps 1546 * @short Meta trunk frame 1547 */ 1548 class YIAX_API IAXMetaTrunkFrame : public RefObject, public Mutex 1549 { 1550 public: 1551 /** 1552 * Constructor. Constructs an outgoing meta trunk frame 1553 * @param engine The engine that owns this frame 1554 * @param addr Remote peer address 1555 * @param timestamps True if miniframes have timestamps, false if not 1556 * @param maxLen Maximum frame length 1557 * @param sendInterval Trunk send interval in milliseconds 1558 */ 1559 IAXMetaTrunkFrame(IAXEngine* engine, const SocketAddr& addr, bool timestamps, 1560 unsigned int maxLen, unsigned int sendInterval); 1561 1562 /** 1563 * Destructor 1564 */ 1565 virtual ~IAXMetaTrunkFrame(); 1566 1567 /** 1568 * Get the remote peer address 1569 * @return The remote peer address 1570 */ addr()1571 inline const SocketAddr& addr() const 1572 { return m_addr; } 1573 1574 /** 1575 * Retrieve the number of calls using this trunk 1576 * @return The number of calls using this trunk 1577 */ calls()1578 inline unsigned int calls() const 1579 { return m_calls; } 1580 1581 /** 1582 * Change the number of calls using this trunk 1583 * @param add True to add a call, false to remove it 1584 */ changeCalls(bool add)1585 inline void changeCalls(bool add) { 1586 Lock lck(this); 1587 if (add) 1588 m_calls++; 1589 else if (m_calls) 1590 m_calls--; 1591 } 1592 1593 /** 1594 * Check if the frame is adding mini frames timestamps 1595 * @return True if the frame is adding mini frames timestamps 1596 */ trunkTimestamps()1597 inline bool trunkTimestamps() const 1598 { return m_trunkTimestamps; } 1599 1600 /** 1601 * Retrieve the send interval 1602 * @return Send interval in milliseconds 1603 */ sendInterval()1604 inline unsigned int sendInterval() const 1605 { return m_sendInterval; } 1606 1607 /** 1608 * Retrieve the frame maximum length 1609 * @return Frame maximum length 1610 */ maxLen()1611 inline unsigned int maxLen() const 1612 { return m_maxLen; } 1613 1614 /** 1615 * Add a mini frame. If no room, send before adding 1616 * @param sCallNo Sorce call number 1617 * @param data Mini frame data 1618 * @param tStamp Mini frame timestamp 1619 * @return The number of data bytes added to trunk, 0 on failure 1620 */ 1621 unsigned int add(u_int16_t sCallNo, const DataBlock& data, u_int32_t tStamp); 1622 1623 /** 1624 * Send this frame to remote peer if the time arrived 1625 * @param now Current time 1626 * @return The result of the write operation 1627 */ 1628 inline bool timerTick(const Time& now = Time()) { 1629 if (m_dataAddIdx == IAX2_TRUNKFRAME_HEADERLENGTH || !m_send) 1630 return false; 1631 Lock lck(this); 1632 return (now > m_send) && doSend(now,true); 1633 } 1634 1635 /** 1636 * Send this frame to remote peer if there is any data in buffer 1637 * @return The result of the write operation 1638 */ send()1639 inline bool send() { 1640 if (m_dataAddIdx == IAX2_TRUNKFRAME_HEADERLENGTH) 1641 return false; 1642 Lock lck(this); 1643 return m_dataAddIdx != IAX2_TRUNKFRAME_HEADERLENGTH && doSend(); 1644 } 1645 1646 private: IAXMetaTrunkFrame()1647 IAXMetaTrunkFrame() {} // No default constructor 1648 // Send this frame to remote peer 1649 bool doSend(const Time& now = Time(), bool onTime = false); 1650 // Set timestamp and next time to send setTimestamp(u_int64_t now)1651 inline void setTimestamp(u_int64_t now) { 1652 m_timeStamp = now; 1653 m_send = now + (u_int64_t)m_sendInterval * 1000; 1654 } 1655 // Set next time to send setSendTime(u_int64_t now)1656 inline void setSendTime(u_int64_t now) 1657 { m_send = now + (u_int64_t)m_sendInterval * 1000; } 1658 1659 // Set the timestamp of this frame setTimestamp(u_int32_t tStamp)1660 inline void setTimestamp(u_int32_t tStamp) { 1661 m_data[4] = (u_int8_t)(tStamp >> 24); 1662 m_data[5] = (u_int8_t)(tStamp >> 16); 1663 m_data[6] = (u_int8_t)(tStamp >> 8); 1664 m_data[7] = (u_int8_t)tStamp; 1665 } 1666 1667 unsigned int m_calls; // The number of calls using it 1668 u_int8_t* m_data; // Data buffer 1669 u_int16_t m_dataAddIdx; // Current add index 1670 u_int64_t m_timeStamp; // First time data was added 1671 u_int64_t m_send; // Time to send 1672 u_int32_t m_lastSentTs; // Last sent timestamp 1673 unsigned int m_sendInterval;// Send interval in milliseconds 1674 IAXEngine* m_engine; // The engine that owns this frame 1675 SocketAddr m_addr; // Remote peer address 1676 bool m_trunkTimestamps; // Trunk type: with(out) timestamps 1677 unsigned int m_maxLen; // Max frame length 1678 unsigned int m_maxDataLen; // Max frame data length 1679 unsigned char m_miniHdrLen; // Miniframe header length 1680 }; 1681 1682 /** 1683 * This class holds data used by transaction to sync media. 1684 * The mutexes are not reentrant 1685 * @short IAX2 transaction media data 1686 */ 1687 class YIAX_API IAXMediaData 1688 { 1689 friend class IAXTransaction; 1690 public: 1691 /** 1692 * Constructor 1693 */ IAXMediaData()1694 inline IAXMediaData() 1695 : m_inMutex(false,"IAXTransaction::InMedia"), 1696 m_outMutex(false,"IAXTransaction::OutMedia"), 1697 m_startedIn(false), m_startedOut(false), 1698 m_outStartTransTs(0), m_outFirstSrcTs(0), 1699 m_lastOut(0), m_lastIn(0), m_sent(0), m_sentBytes(0), 1700 m_recv(0), m_recvBytes(0), m_ooPackets(0), m_ooBytes(0), 1701 m_showInNoFmt(true), m_showOutOldTs(true), 1702 m_dropOut(0), m_dropOutBytes(0) 1703 {} 1704 1705 /** 1706 * Increase drop out data 1707 * @param len The number of dropped bytes 1708 */ dropOut(unsigned int len)1709 inline void dropOut(unsigned int len) { 1710 if (len) { 1711 m_dropOut++; 1712 m_dropOutBytes += len; 1713 } 1714 } 1715 1716 /** 1717 * Print statistics 1718 * @param buf Destination buffer 1719 */ 1720 void print(String& buf); 1721 1722 protected: 1723 Mutex m_inMutex; 1724 Mutex m_outMutex; 1725 bool m_startedIn; // Incoming media started 1726 bool m_startedOut; // Outgoing media started 1727 int m_outStartTransTs; // Transaction timestamp where media send started 1728 unsigned int m_outFirstSrcTs; // First outgoing source packet timestamp as received from source 1729 u_int32_t m_lastOut; // Last transmitted mini timestamp 1730 u_int32_t m_lastIn; // Last received timestamp 1731 unsigned int m_sent; // Packets sent 1732 unsigned int m_sentBytes; // Bytes sent 1733 unsigned int m_recv; // Packets received 1734 unsigned int m_recvBytes; // Bytes received 1735 unsigned int m_ooPackets; // Dropped received out of order packets 1736 unsigned int m_ooBytes; // Dropped received out of order bytes 1737 bool m_showInNoFmt; // Show incoming media arrival without format debug 1738 bool m_showOutOldTs; // Show dropped media out debug message 1739 unsigned int m_dropOut; // The number of dropped outgoing packets 1740 unsigned int m_dropOutBytes; // The number of dropped outgoing bytes 1741 }; 1742 1743 /** 1744 * This class holds all the data needded for the management of an IAX2 transaction 1745 * which might be a call leg, a register/unregister or a poke one 1746 * @short An IAX2 transaction 1747 */ 1748 class YIAX_API IAXTransaction : public RefObject, public Mutex 1749 { 1750 friend class IAXEvent; 1751 friend class IAXEngine; 1752 public: 1753 /** 1754 * The transaction type as enumeration 1755 */ 1756 enum Type { 1757 Incorrect, // Unsupported/unknown type 1758 New, // Media exchange call 1759 RegReq, // Registration 1760 RegRel, // Registration release 1761 Poke, // Ping 1762 //FwDownl, 1763 }; 1764 1765 /** 1766 * The transaction state as enumeration 1767 */ 1768 enum State { 1769 Connected, // Call leg established (Accepted) for transactions of type New 1770 NewLocalInvite, // New outgoing transaction: Poke/New/RegReq/RegRel 1771 NewLocalInvite_AuthRecv, // Auth request received for an outgoing transaction 1772 NewLocalInvite_RepSent, // Auth reply sent for an outgoing transaction 1773 NewRemoteInvite, // New incoming transaction: Poke/New/RegReq/RegRel 1774 NewRemoteInvite_AuthSent, // Auth sent for an incoming transaction 1775 NewRemoteInvite_RepRecv, // Auth reply received for an incoming transaction 1776 Unknown, // Initial state 1777 Terminated, // Terminated. No more frames accepted 1778 Terminating, // Terminating. Wait for ACK or timeout to terminate 1779 }; 1780 1781 /** 1782 * Constructs an incoming transaction from a received full frame with an IAX 1783 * control message that needs a new transaction 1784 * @param engine The engine that owns this transaction 1785 * @param frame A valid full frame 1786 * @param lcallno Local call number 1787 * @param addr Address from where the frame was received 1788 * @param data Pointer to arbitrary user data 1789 */ 1790 static IAXTransaction* factoryIn(IAXEngine* engine, IAXFullFrame* frame, u_int16_t lcallno, const SocketAddr& addr, 1791 void* data = 0); 1792 1793 /** 1794 * Constructs an outgoing transaction with an IAX control message that needs a new transaction 1795 * @param engine The engine that owns this transaction 1796 * @param type Transaction type 1797 * @param lcallno Local call number 1798 * @param addr Address to use 1799 * @param ieList Starting IE list 1800 * @param data Pointer to arbitrary user data 1801 */ 1802 static IAXTransaction* factoryOut(IAXEngine* engine, Type type, u_int16_t lcallno, const SocketAddr& addr, 1803 IAXIEList& ieList, void* data = 0); 1804 1805 /** 1806 * Destructor 1807 */ 1808 virtual ~IAXTransaction(); 1809 1810 /** 1811 * The IAX engine this transaction belongs to 1812 * @return Pointer to the IAXEngine of this transaction 1813 */ getEngine()1814 inline IAXEngine* getEngine() const 1815 { return m_engine; } 1816 1817 /** 1818 * Get the type of this transaction 1819 * @return The type of the transaction as enumeration 1820 */ type()1821 inline Type type() const 1822 { return m_type; } 1823 1824 /** 1825 * Retrieve transaction type name 1826 * @return Transaction type name 1827 */ typeName()1828 inline const char* typeName() 1829 { return typeName(type()); } 1830 1831 /** 1832 * Get the state of this transaction 1833 * @return The state of the transaction as enumeration 1834 */ state()1835 inline State state() const 1836 { return m_state; } 1837 1838 /** 1839 * Retrieve the transaction state name 1840 * @return Transaction state name 1841 */ stateName()1842 inline const char* stateName() 1843 { return stateName(state()); } 1844 1845 /** 1846 * Get the timestamp of this transaction 1847 * @return The timestamp of this transaction 1848 */ timeStamp()1849 inline u_int64_t timeStamp() const 1850 { return Time::msecNow() - m_timeStamp; } 1851 1852 /** 1853 * Get the direction of this transaction 1854 * @return True if it is an outgoing transaction 1855 */ outgoing()1856 inline bool outgoing() const 1857 { return m_localInitTrans; } 1858 1859 /** 1860 * Store a pointer to arbitrary user data 1861 * @param data User provided pointer 1862 */ setUserData(void * data)1863 inline void setUserData(void* data) 1864 { m_userdata = data; } 1865 1866 /** 1867 * Return the opaque user data stored in the transaction 1868 * @return Pointer set by user 1869 */ getUserData()1870 inline void* getUserData() const 1871 { return m_userdata; } 1872 1873 /** 1874 * Retrieve the local call number 1875 * @return 15-bit local call number 1876 */ localCallNo()1877 inline u_int16_t localCallNo() const 1878 { return m_lCallNo; } 1879 1880 /** 1881 * Retrieve the remote call number 1882 * @return 15-bit remote call number 1883 */ remoteCallNo()1884 inline u_int16_t remoteCallNo() const 1885 { return m_rCallNo; } 1886 1887 /** 1888 * Retrieve the remote host+port address 1889 * @return A reference to the remote address 1890 */ remoteAddr()1891 inline const SocketAddr& remoteAddr() const 1892 { return m_addr; } 1893 1894 /** 1895 * Retrieve the username 1896 * @return A reference to the username 1897 */ username()1898 inline const String& username() 1899 { return m_username; } 1900 1901 /** 1902 * Retrieve the calling number 1903 * @return A reference to the calling number 1904 */ callingNo()1905 inline const String& callingNo() 1906 { return m_callingNo; } 1907 1908 /** 1909 * Retrieve the calling name 1910 * @return A reference to the calling name 1911 */ callingName()1912 inline const String& callingName() 1913 { return m_callingName; } 1914 1915 /** 1916 * Retrieve the called number 1917 * @return A reference to the called number 1918 */ calledNo()1919 inline const String& calledNo() 1920 { return m_calledNo; } 1921 1922 /** 1923 * Retrieve the called context 1924 * @return A reference to the called context 1925 */ calledContext()1926 inline const String& calledContext() 1927 { return m_calledContext; } 1928 1929 /** 1930 * Retrieve the challenge sent/received during authentication 1931 * @return A reference to the challenge 1932 */ challenge()1933 inline const String& challenge() 1934 { return m_challenge; } 1935 1936 /** 1937 * Retrieve the media of a given type 1938 * @param type Media type to retrieve 1939 * @return IAXFormat pointer or 0 for invalid type 1940 */ getFormat(int type)1941 inline IAXFormat* getFormat(int type) { 1942 if (type == IAXFormat::Audio) 1943 return &m_format; 1944 if (type == IAXFormat::Video) 1945 return &m_formatVideo; 1946 return 0; 1947 } 1948 1949 /** 1950 * Retrieve the media data for a given type 1951 * @param type Media type to retrieve 1952 * @return IAXMediaData pointer or 0 for invalid type 1953 */ getData(int type)1954 inline IAXMediaData* getData(int type) { 1955 if (type == IAXFormat::Audio) 1956 return &m_dataAudio; 1957 if (type == IAXFormat::Video) 1958 return &m_dataVideo; 1959 return 0; 1960 } 1961 1962 /** 1963 * Retrieve the media format used during initialization 1964 * @param type Media type to retrieve 1965 * @return The initial media format for the given type 1966 */ format(int type)1967 inline u_int32_t format(int type) { 1968 IAXFormat* fmt = getFormat(type); 1969 return fmt ? fmt->format() : 0; 1970 } 1971 1972 /** 1973 * Retrieve the incoming media format 1974 * @param type Media type to retrieve 1975 * @return The incoming media format for the given type 1976 */ formatIn(int type)1977 inline u_int32_t formatIn(int type) { 1978 IAXFormat* fmt = getFormat(type); 1979 return fmt ? fmt->in() : 0; 1980 } 1981 1982 /** 1983 * Retrieve the outgoing media format 1984 * @param type Media type to retrieve 1985 * @return The outgoing media format for the given type 1986 */ formatOut(int type)1987 inline u_int32_t formatOut(int type) { 1988 IAXFormat* fmt = getFormat(type); 1989 return fmt ? fmt->out() : 0; 1990 } 1991 1992 /** 1993 * Retrieve the media capability of this transaction 1994 * @return The media capability of this transaction 1995 */ capability()1996 inline u_int32_t capability() const 1997 { return m_capability; } 1998 1999 /** 2000 * Retrieve the expiring time for a register/unregister transaction 2001 * @return The expiring time for a register/unregister transaction 2002 */ expire()2003 inline u_int32_t expire() const 2004 { return m_expire; } 2005 2006 /** 2007 * Retrieve the authentication data sent/received during authentication 2008 * @return A reference to the authentication data 2009 */ authdata()2010 inline const String& authdata() 2011 { return m_authdata; } 2012 2013 /** 2014 * Set the destroy flag 2015 */ setDestroy()2016 inline void setDestroy() 2017 { m_destroy = true; } 2018 2019 /** 2020 * Start an outgoing transaction. 2021 * This method is thread safe 2022 */ 2023 void start(); 2024 2025 /** 2026 * Process a frame from remote peer. 2027 * This method is thread safe 2028 * @param frame IAX frame belonging to this transaction to process 2029 * @return 'this' if successful or NULL if the frame is invalid 2030 */ 2031 IAXTransaction* processFrame(IAXFrame* frame); 2032 2033 /** 2034 * Process received media data 2035 * @param data Received data 2036 * @param tStamp Mini frame timestamp multiplied by format multiplier 2037 * @param type Media type 2038 * @param full True if received in a full frame 2039 * @param mark Mark flag 2040 * @return 0 2041 */ 2042 IAXTransaction* processMedia(DataBlock& data, u_int32_t tStamp, 2043 int type = IAXFormat::Audio, bool full = false, bool mark = false); 2044 2045 /** 2046 * Send media data to remote peer. Update the outgoing media format if changed 2047 * @param data Data to send 2048 * @param tStamp Data timestamp 2049 * @param format Data format 2050 * @param type Media type 2051 * @param mark Mark flag 2052 * @return The number of bytes sent 2053 */ 2054 unsigned int sendMedia(const DataBlock& data, unsigned int tStamp, u_int32_t format, 2055 int type = IAXFormat::Audio, bool mark = false); 2056 2057 /** 2058 * Get an IAX event from the queue 2059 * This method is thread safe. 2060 * @param now Current time 2061 * @return Pointer to an IAXEvent or 0 if none available 2062 */ 2063 IAXEvent* getEvent(const Time& now = Time()); 2064 2065 /** 2066 * Get the maximum allowed number of full frames in the incoming frame list 2067 * @return The maximum allowed number of full frames in the incoming frame list 2068 */ 2069 static unsigned char getMaxFrameList(); 2070 2071 /** 2072 * Set the maximum allowed number of full frames in the incoming frame list 2073 * @param value The new value of m_maxInFrames 2074 * @return False if value is greater then IAX2_MAX_TRANSINFRAMELIST 2075 */ 2076 static bool setMaxFrameList(unsigned char value); 2077 2078 /** 2079 * Send an ANSWER frame to remote peer 2080 * This method is thread safe 2081 * @return False if the current transaction state is not Connected 2082 */ sendAnswer()2083 inline bool sendAnswer() 2084 { return sendConnected(IAXFullFrame::Answer); } 2085 2086 /** 2087 * Send a RINGING frame to remote peer 2088 * This method is thread safe 2089 * @return False if the current transaction state is not Connected 2090 */ sendRinging()2091 inline bool sendRinging() 2092 { return sendConnected(IAXFullFrame::Ringing); } 2093 2094 /** 2095 * Send a PROCEEDING frame to remote peer 2096 * This method is thread safe 2097 * @return False if the current transaction state is not Connected 2098 */ sendProgress()2099 inline bool sendProgress() 2100 { return sendConnected(IAXFullFrame::Proceeding); } 2101 2102 /** 2103 * Send an ACCEPT/REGACK frame to remote peer 2104 * This method is thread safe 2105 * @param expires Optional pointer to expiring time for register transactions 2106 * @return False if the transaction type is not New and state is NewRemoteInvite or NewRemoteInvite_AuthRep or 2107 * if the transaction type is not RegReq and state is NewRemoteInvite or 2108 * type is not RegReq/RegRel and state is NewRemoteInvite_AuthRep 2109 */ 2110 bool sendAccept(unsigned int* expires = 0); 2111 2112 /** 2113 * Send a HANGUP frame to remote peer 2114 * This method is thread safe 2115 * @param cause Optional reason for hangup 2116 * @param code Optional code of reason 2117 * @return False if the transaction type is not New or state is Terminated/Terminating 2118 */ 2119 bool sendHangup(const char* cause = 0, u_int8_t code = 0); 2120 2121 /** 2122 * Send a REJECT/REGREJ frame to remote peer 2123 * This method is thread safe 2124 * @param cause Optional reason for reject 2125 * @param code Optional code of reason 2126 * @return False if the transaction type is not New/RegReq/RegRel or state is Terminated/Terminating 2127 */ 2128 bool sendReject(const char* cause = 0, u_int8_t code = 0); 2129 2130 /** 2131 * Send an AUTHREQ/REGAUTH frame to remote peer 2132 * This method is thread safe 2133 * @return False if the current transaction state is not NewRemoteInvite 2134 */ 2135 bool sendAuth(); 2136 2137 /** 2138 * Send an AUTHREP/REGREQ/REGREL frame to remote peer as a response to AUTHREQ/REGREQ/REGREL 2139 * This method is thread safe 2140 * @param response Response to send 2141 * @return False if the current transaction state is not NewLocalInvite_AuthRecv 2142 */ 2143 bool sendAuthReply(const String& response); 2144 2145 /** 2146 * Send a DTMF frame to remote peer 2147 * This method is thread safe 2148 * @param dtmf DTMF char to send 2149 * @return False if the current transaction state is not Connected or dtmf is grater then 127 2150 */ sendDtmf(u_int8_t dtmf)2151 inline bool sendDtmf(u_int8_t dtmf) 2152 { return dtmf <= 127 ? sendConnected((IAXFullFrame::ControlType)dtmf,IAXFrame::DTMF) : false; } 2153 2154 /** 2155 * Send a TEXT frame to remote peer 2156 * This method is thread safe 2157 * @param text Text to send 2158 * @return False if the current transaction state is not Connected 2159 */ 2160 bool sendText(const char* text); 2161 2162 /** 2163 * Send a NOISE frame to remote peer 2164 * This method is thread safe 2165 * @param noise Noise value to send 2166 * @return False if the current transaction state is not Connected or noise is grater then 127 2167 */ sendNoise(u_int8_t noise)2168 inline bool sendNoise(u_int8_t noise) 2169 { return noise <= 127 ? sendConnected((IAXFullFrame::ControlType)noise,IAXFrame::Noise) : false; } 2170 2171 /** 2172 * Abort a registration transaction 2173 * This method is thread safe 2174 * @return False transaction is not a registration one or is already terminating 2175 */ 2176 bool abortReg(); 2177 2178 /** 2179 * Enable trunking for this transaction 2180 * @param trunkFrame Pointer to IAXMetaTrunkFrame used to send trunked media 2181 * @param efficientUse Use or not the trunk based on calls using it 2182 * @return False trunking is already enabled for this transactio or trunkFrame is 0 2183 */ 2184 bool enableTrunking(IAXMetaTrunkFrame* trunkFrame, bool efficientUse); 2185 2186 /** 2187 * Process a received call token 2188 * This method is thread safe 2189 * @param callToken Received call token 2190 */ 2191 void processCallToken(const DataBlock& callToken); 2192 2193 /** 2194 * Process incoming audio miniframes from trunk without timestamps 2195 * @param ts Trunk frame timestamp 2196 * @param blocks Received blocks 2197 * @param now Current time 2198 */ 2199 void processMiniNoTs(u_int32_t ts, ObjList& blocks, const Time& now = Time()); 2200 2201 /** 2202 * Print transaction data on stdin 2203 * @param printStats True to print media statistics 2204 * @param printFrames True to print in/out pending frames 2205 * @param location Additional location info to be shown in debug 2206 */ 2207 void print(bool printStats = false, bool printFrames = false, const char* location = "status"); 2208 2209 /** 2210 * Retrieve transaction type name from transaction type 2211 * @param type Transaction type 2212 * @return Requested type name 2213 */ typeName(int type)2214 static inline const char* typeName(int type) 2215 { return lookup(type,s_typeName); } 2216 2217 /** 2218 * Retrieve transaction state name 2219 * @param state Transaction state 2220 * @return Requested state name 2221 */ stateName(int state)2222 static inline const char* stateName(int state) 2223 { return lookup(state,s_stateName); } 2224 2225 /** 2226 * Transaction type name 2227 */ 2228 static const TokenDict s_typeName[]; 2229 2230 /** 2231 * Transaction state name 2232 */ 2233 static const TokenDict s_stateName[]; 2234 2235 /** 2236 * Standard message sent if unsupported/unknown/none authentication methosd was received 2237 */ 2238 static String s_iax_modNoAuthMethod; 2239 2240 /** 2241 * Standard message sent if unsupported/unknown/none media format was received 2242 */ 2243 static String s_iax_modNoMediaFormat; 2244 2245 /** 2246 * Standard message sent if the received authentication data is incorrect 2247 */ 2248 static String s_iax_modInvalidAuth; 2249 2250 /** 2251 * Standard message sent if a received frame doesn't have an username information element 2252 */ 2253 static String s_iax_modNoUsername; 2254 2255 protected: 2256 /** 2257 * Constructor: constructs an incoming transaction from a received full frame with an IAX 2258 * control message that needs a new transaction 2259 * @param engine The engine that owns this transaction 2260 * @param frame A valid full frame 2261 * @param lcallno Local call number 2262 * @param addr Address from where the frame was received 2263 * @param data Pointer to arbitrary user data 2264 */ 2265 IAXTransaction(IAXEngine* engine, IAXFullFrame* frame, u_int16_t lcallno, const SocketAddr& addr, 2266 void* data = 0); 2267 2268 /** 2269 * Constructor: constructs an outgoing transaction with an IAX control message that needs a new transaction 2270 * @param engine The engine that owns this transaction 2271 * @param type Transaction type: see Type enumeration 2272 * @param lcallno Local call number 2273 * @param addr Address to use 2274 * @param ieList Starting IE list 2275 * @param data Pointer to arbitrary user data 2276 */ 2277 IAXTransaction(IAXEngine* engine, Type type, u_int16_t lcallno, const SocketAddr& addr, IAXIEList& ieList, 2278 void* data = 0); 2279 2280 /** 2281 * Cleanup 2282 */ 2283 virtual void destroyed(); 2284 2285 /** 2286 * Init data members from an IE list 2287 * @param ieList IE list to init from 2288 */ 2289 void init(IAXIEList& ieList); 2290 2291 /** 2292 * Increment sequence numbers (inbound or outbound) for the frames that need it 2293 * @param frame Received frame if inbound is true, otherwise a transmitted one 2294 * @param inbound True for inbound frames 2295 * @return True if incremented. 2296 */ 2297 bool incrementSeqNo(const IAXFullFrame* frame, bool inbound); 2298 2299 /** 2300 * Test if frame is acceptable (not an out of order or a late one) 2301 * @param frame Frame to test 2302 * @return True if frame can be added to incoming frame list 2303 */ 2304 bool isFrameAcceptable(const IAXFullFrame* frame); 2305 2306 /** 2307 * Change the transaction state 2308 * @param newState the new transaction state 2309 * @return False if trying to change a termination state into a non termination one 2310 */ 2311 bool changeState(State newState); 2312 2313 /** 2314 * Terminate the transaction. 2315 * @param evType IAXEvent type to generate 2316 * @param local If true it is a locally generated event 2317 * @param frame Frame to build event from 2318 * @param createIEList If true create IE list in the generated event 2319 * @return Pointer to a valid IAXEvent 2320 */ 2321 IAXEvent* terminate(u_int8_t evType, bool local, IAXFullFrame* frame = 0, bool createIEList = true); 2322 2323 /** 2324 * Wait for ACK to terminate the transaction. No more events will be generated 2325 * @param evType IAXEvent type to generate 2326 * @param local If true it is a locally generated event 2327 * @param frame Frame to build event from 2328 * @return Pointer to a valid IAXEvent if evType if non 0, 0 otherwise 2329 */ 2330 IAXEvent* waitForTerminate(u_int8_t evType = 0, bool local = true, IAXFullFrame* frame = 0); 2331 2332 /** 2333 * Constructs an IAXFrameOut frame, send it to remote peer and put it in the transmission list 2334 * This method is thread safe 2335 * @param type Frame type 2336 * @param subclass Frame subclass 2337 * @param data Frame IE list 2338 * @param len Frame IE list length 2339 * @param tStamp Frame timestamp. If 0 the transaction timestamp will be used 2340 * @param ackOnly Frame's acknoledge only flag 2341 * @param mark Frame mark flag 2342 */ 2343 void postFrame(IAXFrame::Type type, u_int32_t subclass, void* data = 0, u_int16_t len = 0, u_int32_t tStamp = 0, 2344 bool ackOnly = false, bool mark = false); 2345 2346 /** 2347 * Constructs an IAXFrameOut frame, send it to remote peer and put it in the transmission list 2348 * This method is thread safe 2349 * @param type Frame type 2350 * @param subclass Frame subclass 2351 * @param ies Frame IE list 2352 * @param tStamp Frame timestamp. If 0 the transaction timestamp will be used 2353 * @param ackOnly Frame's acknoledge only flag 2354 */ 2355 void postFrameIes(IAXFrame::Type type, u_int32_t subclass, IAXIEList* ies, u_int32_t tStamp = 0, 2356 bool ackOnly = false); 2357 2358 /** 2359 * Send a full frame to remote peer 2360 * @param frame Frame to send 2361 * @param vnak If true the transmission is a response to a VNAK frame 2362 * @return True on success 2363 */ 2364 bool sendFrame(IAXFrameOut* frame, bool vnak = false); 2365 2366 /** 2367 * Create an event 2368 * @param evType Event type 2369 * @param local If true it is a locally generated event. 2370 * @param frame Frame to create from 2371 * @param newState The transaction new state 2372 * @return Pointer to an IAXEvent or 0 (invalid IE list) 2373 */ 2374 IAXEvent* createEvent(u_int8_t evType, bool local, IAXFullFrame* frame, State newState); 2375 2376 /** 2377 * Create an event from a received frame that is a response to a sent frame and 2378 * change the transaction state to newState. Remove the response from incoming list. 2379 * @param frame Frame to create response for 2380 * @param findType Frame type to find 2381 * @param findSubclass Frame subclass to find 2382 * @param evType Event type to generate 2383 * @param local Local flag for the generated event. 2384 * @param newState New transaction state if an event was generated 2385 * @return Pointer to an IAXEvent or 0 (invalid IE list) 2386 */ 2387 IAXEvent* createResponse(IAXFrameOut* frame, u_int8_t findType, u_int8_t findSubclass, u_int8_t evType, bool local, State newState); 2388 2389 /** 2390 * Find a response for a previously sent frame 2391 * @param frame Frame to find response for 2392 * @param delFrame Delete frame flag. If true on exit, a response was found 2393 * @return Pointer to an IAXEvent or 0 2394 */ 2395 IAXEvent* getEventResponse(IAXFrameOut* frame, bool& delFrame); 2396 2397 /** 2398 * Find a response for a previously sent frame if the transaction type is New 2399 * @param frame Frame to find response for 2400 * @param delFrame Delete frame flag. If true on exit, a response was found 2401 * @return Pointer to an IAXEvent or 0 2402 */ 2403 IAXEvent* getEventResponse_New(IAXFrameOut* frame, bool& delFrame); 2404 2405 /** 2406 * Process an authentication request. If valid, send an authentication reply 2407 * @param event Already generated event 2408 * @return Pointer to a valid IAXEvent 2409 */ 2410 IAXEvent* processAuthReq(IAXEvent* event); 2411 2412 /** 2413 * Process an accept. If not valid (call m_engine->acceptFormatAndCapability) send a reject. 2414 * Otherwise return the event 2415 * @param event Already generated event 2416 * @return Pointer to a valid IAXEvent 2417 */ 2418 IAXEvent* processAccept(IAXEvent* event); 2419 2420 /** 2421 * Process an authentication reply 2422 * @param event Already generated event 2423 * @return Pointer to a valid IAXEvent 2424 */ 2425 IAXEvent* processAuthRep(IAXEvent* event); 2426 2427 /** 2428 * Find a response for a previously sent frame if the transaction type is RegReq/RegRel 2429 * @param frame Frame to find response for 2430 * @param delFrame Delete frame flag. If true on exit, a response was found 2431 * @return Pointer to an IAXEvent or 0 2432 */ 2433 IAXEvent* getEventResponse_Reg(IAXFrameOut* frame, bool& delFrame); 2434 2435 /** 2436 * Update transaction data from the event 2437 * @param event Already generated event 2438 * @return The received event 2439 */ 2440 IAXEvent* processRegAck(IAXEvent* event); 2441 2442 /** 2443 * Find out if an incoming frame would start a transaction 2444 * @param frame Frame to process 2445 * @param delFrame Delete frame flag. If true on exit, frame is valid 2446 * @return Pointer to an IAXEvent or 0 2447 */ 2448 IAXEvent* getEventStartTrans(IAXFullFrame* frame, bool& delFrame); 2449 2450 /** 2451 * Find out if a frame is a remote request 2452 * @param frame Frame to process 2453 * @param delFrame Delete rame flag. If true on exit, a request was found 2454 * @return Pointer to an IAXEvent or 0 2455 */ 2456 IAXEvent* getEventRequest(IAXFullFrame* frame, bool& delFrame); 2457 2458 /** 2459 * Find out if a frame is a remote request if transaction type is New 2460 * @param frame Frame to process 2461 * @param delFrame Delete rame flag. If true on exit, a request was found 2462 * @return Pointer to an IAXEvent or 0 2463 */ 2464 IAXEvent* getEventRequest_New(IAXFullFrame* frame, bool& delFrame); 2465 2466 /** 2467 * Search for a frame in m_inFrames having the given type and subclass 2468 * @param type Frame type to find. 2469 * @param subclass Frame subclass to find. 2470 * @return Pointer to frame if found or 0. 2471 */ 2472 IAXFullFrame* findInFrame(IAXFrame::Type type, u_int32_t subclass); 2473 2474 /** 2475 * Search in m_inFrames for a frame with the same timestamp as frameOut and deletes it. 2476 * @param frameOut Frame to find response for 2477 * @param type Frame type to find 2478 * @param subclass Frame subclass to find 2479 * @return True if found. 2480 */ 2481 bool findInFrameTimestamp(const IAXFullFrame* frameOut, IAXFrame::Type type, u_int32_t subclass); 2482 2483 /** 2484 * Search in m_inFrames for an ACK frame which confirm the received frame and deletes it 2485 * @param frameOut Frame to find response for 2486 * @return True if found. 2487 */ 2488 bool findInFrameAck(const IAXFullFrame* frameOut); 2489 2490 /** 2491 * Acknoledge the last received full frame 2492 */ 2493 void ackInFrames(); 2494 2495 /** 2496 * Send a frame to remote peer in state Connected 2497 * This method is thread safe 2498 * @param subclass Frame subclass to send 2499 * @param frametype Frame type to send 2500 * @return False if the current transaction state is not Connected 2501 */ 2502 bool sendConnected(IAXFullFrame::ControlType subclass, IAXFrame::Type frametype = IAXFrame::Control); 2503 2504 /** 2505 * Send an ACK frame 2506 * @param frame Aknoledged frame 2507 */ 2508 void sendAck(const IAXFullFrame* frame); 2509 2510 /** 2511 * Send an VNAK frame 2512 */ 2513 void sendVNAK(); 2514 2515 /** 2516 * Send an Unsupport frame 2517 * @param subclass Unsupported frame's subclass 2518 */ 2519 void sendUnsupport(u_int32_t subclass); 2520 2521 /** 2522 * Internal protocol outgoing frames processing (PING/LAGRQ) 2523 * @param frame Frame to process 2524 * @param delFrame Delete frame flag. If true on exit, a response was found 2525 * @return 0. 2526 */ 2527 IAXEvent* processInternalOutgoingRequest(IAXFrameOut* frame, bool& delFrame); 2528 2529 /** 2530 * Internal protocol incoming frames processing (PING/LAGRQ) 2531 * @param frame Frame to process 2532 * @param delFrame Delete frame flag. If true on exit, a request was found 2533 * @return 0. 2534 */ 2535 IAXEvent* processInternalIncomingRequest(const IAXFullFrame* frame, bool& delFrame); 2536 2537 /** 2538 * Process mid call control frames 2539 * @param frame Frame to process 2540 * @param delFrame Delete frame flag. If true on exit, a request was found 2541 * @return A valid IAXEvent or 0 2542 */ 2543 IAXEvent* processMidCallControl(IAXFullFrame* frame, bool& delFrame); 2544 2545 /** 2546 * Process mid call IAX control frames 2547 * @param frame Frame to process 2548 * @param delFrame Delete frame flag. If true on exit, a request was found 2549 * @return A valid IAXEvent or 0 2550 */ 2551 IAXEvent* processMidCallIAXControl(IAXFullFrame* frame, bool& delFrame); 2552 2553 /** 2554 * Test if frame is a Reject/RegRej frame 2555 * @param frame Frame to process. 2556 * @param delFrame Delete frame flag. If true on exit, a request was found 2557 * @return A valid IAXEvent or 0. 2558 */ 2559 IAXEvent* remoteRejectCall(IAXFullFrame* frame, bool& delFrame); 2560 2561 /** 2562 * Process received media full frames 2563 * @param frame Received frame 2564 * @param type Media type 2565 * @return 0 2566 */ 2567 IAXTransaction* processMediaFrame(const IAXFullFrame* frame, int type); 2568 2569 /** 2570 * Send all frames from outgoing queue with outbound sequence number starting with seqNo. 2571 * @param seqNo Requested sequence number 2572 * @return 0 2573 */ 2574 IAXTransaction* retransmitOnVNAK(u_int16_t seqNo); 2575 2576 /** 2577 * Generate a Reject event after internally rejecting a transaction 2578 * @param reason The reason of rejecting 2579 * @param code Error code 2580 * @return A valid IAXEvent 2581 */ 2582 IAXEvent* internalReject(const char* reason, u_int8_t code); 2583 2584 /** 2585 * Event terminated feedback 2586 * This method is thread safe 2587 * @param event The event notifying termination 2588 */ 2589 void eventTerminated(IAXEvent* event); 2590 2591 /** 2592 * Set the current event 2593 * @param event The event notifying termination 2594 * @return event 2595 */ keepEvent(IAXEvent * event)2596 inline IAXEvent* keepEvent(IAXEvent* event) { 2597 m_currentEvent = event; 2598 return event; 2599 } 2600 2601 private: 2602 void adjustTStamp(u_int32_t& tStamp); 2603 void postFrame(IAXFrameOut* frame); 2604 void receivedVoiceMiniBeforeFull(); 2605 void resetTrunk(); 2606 void init(); 2607 void setPendingEvent(IAXEvent* ev = 0); restartTrunkIn(u_int64_t now,u_int32_t ts)2608 inline void restartTrunkIn(u_int64_t now, u_int32_t ts) { 2609 m_trunkInStartTime = now; 2610 u_int64_t dt = (now - m_lastVoiceFrameIn) / 1000; 2611 m_trunkInTsDelta = m_lastVoiceFrameInTs + (u_int32_t)dt; 2612 m_trunkInFirstTs = ts; 2613 } 2614 // Process accept format and caps 2615 bool processAcceptFmt(IAXIEList* list); 2616 // Process queued ACCEPT. Reject with given reason/code if not found 2617 // Reject with 'nomedia' if found and format is not acceptable 2618 IAXEvent* checkAcceptRecv(const char* reason, u_int8_t code); 2619 2620 // Params 2621 bool m_localInitTrans; // True: local initiated transaction 2622 bool m_localReqEnd; // Local client requested terminate 2623 Type m_type; // Transaction type 2624 State m_state; // Transaction state 2625 bool m_destroy; // Destroy flag 2626 bool m_accepted; // ACCEPT received and processed 2627 u_int64_t m_timeStamp; // Transaction creation timestamp 2628 u_int64_t m_timeout; // Transaction timeout in Terminating state 2629 SocketAddr m_addr; // Socket 2630 u_int16_t m_lCallNo; // Local peer call id 2631 u_int16_t m_rCallNo; // Remote peer call id 2632 unsigned char m_oSeqNo; // Outgoing frame sequence number 2633 unsigned char m_iSeqNo; // Incoming frame sequence number 2634 IAXEngine* m_engine; // Engine that owns this transaction 2635 void* m_userdata; // Arbitrary user data 2636 u_int32_t m_lastFullFrameOut; // Last transmitted full frame timestamp 2637 IAXMediaData m_dataAudio; 2638 IAXMediaData m_dataVideo; 2639 u_int16_t m_lastAck; // Last ack'd received frame's oseqno 2640 IAXEvent* m_pendingEvent; // Pointer to a pending event or 0 2641 IAXEvent* m_currentEvent; // Pointer to last generated event or 0 2642 // Outgoing frames management 2643 ObjList m_outFrames; // Transaction & protocol control outgoing frames 2644 unsigned int m_retransCount; // Retransmission counter. 0 --> Timeout 2645 unsigned int m_retransInterval; // Frame retransmission interval 2646 // Incoming frames management 2647 ObjList m_inFrames; // Transaction & protocol control incoming frames 2648 static unsigned char m_maxInFrames; // Max frames number allowed in m_inFrames 2649 // Call leg management 2650 u_int32_t m_pingInterval; // Ping remote peer interval 2651 u_int64_t m_timeToNextPing; // Time of the next Ping 2652 // Statistics 2653 u_int32_t m_inTotalFramesCount; // Total received frames 2654 u_int32_t m_inOutOfOrderFrames; // Total out of order frames 2655 u_int32_t m_inDroppedFrames; // Total dropped frames 2656 // Data 2657 IAXAuthMethod::Type m_authmethod; // Authentication method to use 2658 String m_username; // Username 2659 String m_callingNo; // Calling number 2660 String m_callingName; // Calling name 2661 String m_calledNo; // Called number 2662 String m_calledContext; // Called context 2663 String m_challenge; // Challenge 2664 String m_authdata; // Auth data received with auth reply 2665 u_int32_t m_expire; // Registration expiring time 2666 IAXFormat m_format; // Audio format 2667 IAXFormat m_formatVideo; // Video format 2668 u_int32_t m_capability; // Media capability of this transaction 2669 bool m_callToken; // Call token supported/expected 2670 unsigned int m_adjustTsOutThreshold; // Adjust outgoing data timestamp threshold 2671 unsigned int m_adjustTsOutOverrun; // Value used to adjust outgoing data timestamp on data 2672 // overrun (incoming data with rate greater then expected) 2673 unsigned int m_adjustTsOutUnderrun; // Value used to adjust outgoing data timestamp on data 2674 // underrun (incoming data with rate less then expected) 2675 u_int64_t m_lastVoiceFrameIn; // Time we received the last voice frame 2676 u_int32_t m_lastVoiceFrameInTs; // Timestamp in the last received voice frame 2677 int m_reqVoiceVNAK; // Send VNAK if not received full voice frame 2678 // Meta trunking 2679 IAXMetaTrunkFrame* m_trunkFrame; // Reference to a trunk frame if trunking is enabled for this transaction 2680 bool m_trunkFrameCallsSet; // Trunk frame calls increased 2681 bool m_trunkOutEfficientUse; // Use or not the trunk frame based on calls using it 2682 bool m_trunkOutSend; // Currently using the trunk frame 2683 bool m_trunkInSyncUsingTs; // Incoming trunk without timestamps: generate timestamp 2684 // using time or using trunk timestamp 2685 u_int64_t m_trunkInStartTime; // First time we received trunk in data 2686 u_int32_t m_trunkInTsDelta; // Value used to re-build ts: last voice timestamp 2687 u_int32_t m_trunkInTsDiffRestart; // Incoming trunk without timestamp: diff between timestamps at which we restart 2688 u_int32_t m_trunkInFirstTs; // Incoming trunk without timestamp: first trunk timestamp 2689 // Postponed start 2690 IAXIEList* m_startIEs; // Postponed start 2691 }; 2692 2693 /** 2694 * This class holds an event generated by a transaction 2695 * @short Event class 2696 */ 2697 class YIAX_API IAXEvent 2698 { 2699 friend class IAXTransaction; 2700 friend class IAXConnectionlessTransaction; 2701 public: 2702 /** 2703 * Event type as enumeration 2704 */ 2705 enum Type { 2706 DontSet = 0, // Used internal 2707 Invalid, // Invalid frame received 2708 Terminated, // Transaction terminated 2709 Timeout, // Transaction timeout 2710 NotImplemented, // Feature not implemented 2711 New, // New remote transaction 2712 AuthReq, // Auth request 2713 AuthRep, // Auth reply 2714 Accept, // Request accepted 2715 Hangup, // Remote hangup 2716 Reject, // Remote reject 2717 Busy, // Call busy 2718 Text, // Text frame received 2719 Dtmf, // DTMF frame received 2720 Noise, // Noise frame received 2721 Answer, // Call answered 2722 Quelch, // Quelch the call 2723 Unquelch, // Unquelch the call 2724 Progressing, // Call progressing 2725 Ringing, // Ringing 2726 }; 2727 2728 /** 2729 * Destructor 2730 * Dereferences the transaction possibly causing its destruction 2731 */ 2732 ~IAXEvent(); 2733 2734 /** 2735 * Get the type of this event 2736 * @return The type of the event as enumeratio 2737 */ type()2738 inline Type type() const 2739 { return m_type; } 2740 2741 /** 2742 * Check if this is a locally generated event 2743 * @return True if it is a locally generated event 2744 */ local()2745 inline bool local() const 2746 { return m_local; } 2747 2748 /** 2749 * Check if this is a transaction finalization event 2750 * @return True if the transaction has finalized and will be destroyed 2751 */ final()2752 inline bool final() const 2753 { return m_final; } 2754 2755 /** 2756 * Set the final flag. 2757 */ setFinal()2758 inline void setFinal() 2759 { m_final = true; } 2760 2761 /** 2762 * Get the type of the frame that generated the event 2763 * If 0 (internal event), the event consumer must delete the event 2764 * @return Frame type 2765 */ frameType()2766 inline u_int8_t frameType() 2767 { return m_frameType; } 2768 2769 /** 2770 * Get the subclass of the frame that generated the event 2771 * @return Frame subclass 2772 */ subclass()2773 inline u_int32_t subclass() 2774 { return m_subClass; } 2775 2776 /** 2777 * Get the IAX engine this event belongs to, if any 2778 * @return The IAX engine this event belongs to, if any 2779 */ getEngine()2780 inline IAXEngine* getEngine() const 2781 { return m_transaction ? m_transaction->getEngine() : 0; } 2782 2783 /** 2784 * Get the IAX transaction that generated the event, if any 2785 * @return The IAX transaction that generated the event, if any 2786 */ getTransaction()2787 inline IAXTransaction* getTransaction() const 2788 { return m_transaction; } 2789 2790 /** 2791 * Get the opaque user data stored in the transaction 2792 * @return The opaque user data stored in the transaction 2793 */ getUserData()2794 inline void* getUserData() const 2795 { return m_transaction ? m_transaction->getUserData() : 0; } 2796 2797 /** 2798 * Get the IE list 2799 * @return IE list reference 2800 */ getList()2801 inline IAXIEList& getList() 2802 { return *m_ieList; } 2803 2804 protected: 2805 /** 2806 * Constructor 2807 * @param type Event type 2808 * @param local Local flag 2809 * @param final Final flag 2810 * @param transaction IAX transaction that generated the event 2811 * @param frameType The type of the frame that generated the event 2812 * @param subclass The subclass of the frame that generated the event 2813 */ 2814 IAXEvent(Type type, bool local, bool final, IAXTransaction* transaction, u_int8_t frameType = 0, u_int32_t subclass = 0); 2815 2816 /** 2817 * Constructor 2818 * @param type Event type 2819 * @param local Local flag 2820 * @param final Final flag 2821 * @param transaction IAX transaction that generated the event 2822 * @param frame The frame that generated the event 2823 */ 2824 IAXEvent(Type type, bool local, bool final, IAXTransaction* transaction, IAXFullFrame* frame = 0); 2825 2826 private: IAXEvent()2827 inline IAXEvent() {} // Default constructor 2828 2829 Type m_type; // Event type 2830 u_int8_t m_frameType; // Frame type 2831 u_int32_t m_subClass; // Frame subclass 2832 bool m_local; // If true the event is generated locally, the receiver MUST not respond 2833 bool m_final; // Final event flag 2834 IAXTransaction* m_transaction; // Transaction that generated this event 2835 IAXIEList* m_ieList; // IAXInfoElement list 2836 }; 2837 2838 /** 2839 * This class holds all information needded to manipulate all IAX transactions and events 2840 * @short IAX engine class 2841 */ 2842 class YIAX_API IAXEngine : public DebugEnabler, public Mutex 2843 { 2844 public: 2845 /** 2846 * Constructor 2847 * @param iface Address of the interface to use, default all (0.0.0.0) 2848 * @param port UDP port to run the protocol on 2849 * @param format Default media format 2850 * @param capab Media capabilities of this engine 2851 * @param params Optional extra parameter list 2852 * @param name Engine name 2853 */ 2854 IAXEngine(const char* iface, int port, u_int32_t format, u_int32_t capab, 2855 const NamedList* params = 0, const char* name = "iaxengine"); 2856 2857 /** 2858 * Destructor 2859 * Closes all transactions belonging to this engine and flush all queues 2860 */ 2861 virtual ~IAXEngine(); 2862 2863 /** 2864 * Retrieve the engine name 2865 * @return Engine name 2866 */ name()2867 inline const String& name() const 2868 { return m_name; } 2869 2870 /** 2871 * Retrieve the default caller number type 2872 * @return Default caller number type 2873 */ callerNumType()2874 inline u_int8_t callerNumType() const 2875 { return m_callerNumType; } 2876 2877 /** 2878 * Retrieve the default caller number presentation and screening concatenated value 2879 * @return Default caller number presentation and screening 2880 */ callingPres()2881 inline u_int8_t callingPres() const 2882 { return m_callingPres; } 2883 2884 /** 2885 * Add a parsed frame to the transaction list 2886 * @param addr Address from which the frame was received 2887 * @param frame A parsed IAX frame 2888 * @return Pointer to the transaction or 0 to deref the frame 2889 */ 2890 IAXTransaction* addFrame(const SocketAddr& addr, IAXFrame* frame); 2891 2892 /** 2893 * Add a raw frame to the transaction list 2894 * @param addr Address from which the message was received 2895 * @param buf Pointer to the start of the buffer holding the IAX frame 2896 * @param len Length of the message buffer 2897 * @return Pointer to the transaction or 0 2898 */ 2899 IAXTransaction* addFrame(const SocketAddr& addr, const unsigned char* buf, unsigned int len); 2900 2901 /** 2902 * Find a complete transaction. 2903 * This method is thread safe 2904 * @param addr Remote address 2905 * @param rCallNo Remote transaction call number 2906 * @return Referrenced pointer to the transaction or 0 2907 */ 2908 IAXTransaction* findTransaction(const SocketAddr& addr, u_int16_t rCallNo); 2909 2910 /** 2911 * Process media from remote peer. Descendents must override this method 2912 * @param transaction IAXTransaction that owns the call leg 2913 * @param data Media data 2914 * @param tStamp Media timestamp 2915 * @param type Media type 2916 * @param mark Mark flag 2917 */ processMedia(IAXTransaction * transaction,DataBlock & data,u_int32_t tStamp,int type,bool mark)2918 virtual void processMedia(IAXTransaction* transaction, DataBlock& data, u_int32_t tStamp, 2919 int type, bool mark) 2920 {} 2921 2922 /** 2923 * Event processor method. Keeps calling getEvent() and passing 2924 * any events to processEvent() until there are no more events 2925 * @return True if at least one event was processed 2926 */ 2927 bool process(); 2928 2929 /** 2930 * Get the timeout interval sent challenge 2931 * @return Sent challenge timeout interval 2932 */ challengeTout()2933 inline unsigned int challengeTout() const 2934 { return m_challengeTout; } 2935 2936 /** 2937 * Get the maximum allowed frame length 2938 * @return The maximum allowed frame length 2939 */ maxFullFrameDataLen()2940 inline u_int16_t maxFullFrameDataLen() const 2941 { return m_maxFullFrameDataLen; } 2942 2943 /** 2944 * Get the default media format 2945 * @param audio True to retrieve default audio format, false for video format 2946 * @return The default media format 2947 */ 2948 inline u_int32_t format(bool audio = true) const 2949 { return audio ? m_format : m_formatVideo; } 2950 2951 /** 2952 * Get the media capability of this engine 2953 * @return The media capability of this engine 2954 */ capability()2955 inline u_int32_t capability() const 2956 { return m_capability; } 2957 2958 /** 2959 * Retrieve outgoing data timestamp adjust values 2960 * @param thres Adjust outgoing data timestamp threshold 2961 * @param over Value used to adjust outgoing data timestamp on data overrun 2962 * @param under Value used to adjust outgoing data timestamp on data underrun 2963 */ getOutDataAdjust(unsigned int & thres,unsigned int & over,unsigned int & under)2964 inline void getOutDataAdjust(unsigned int& thres, unsigned int& over, 2965 unsigned int& under) const { 2966 thres = m_adjustTsOutThreshold; 2967 over = m_adjustTsOutOverrun; 2968 under = m_adjustTsOutUnderrun; 2969 } 2970 2971 /** 2972 * Initialize outgoing data timestamp adjust values. 2973 * This method is thread safe 2974 * @param params Parameters list 2975 * @param tr Optional transaction to init, initialize the engine's data if 0 2976 */ 2977 void initOutDataAdjust(const NamedList& params, IAXTransaction* tr = 0); 2978 2979 /** 2980 * (Re)Initialize the engine 2981 * @param params Parameter list 2982 */ 2983 void initialize(const NamedList& params); 2984 2985 /** 2986 * Read data from socket 2987 * @param addr Socket to read from 2988 */ 2989 void readSocket(SocketAddr& addr); 2990 2991 /** 2992 * Write data to socket. 2993 * @param buf Data to write 2994 * @param len Data length 2995 * @param addr Socket to write to 2996 * @param frame Optional frame to be printed 2997 * @param sent Pointer to variable to be filled with the number of bytes sent 2998 * @return True on success 2999 */ 3000 bool writeSocket(const void* buf, int len, const SocketAddr& addr, IAXFullFrame* frame = 0, 3001 unsigned int* sent = 0); 3002 3003 /** 3004 * Write a full frame to socket 3005 * @param addr Socket to write to 3006 * @param frame Frame to write 3007 * @return True on success 3008 */ writeSocket(const SocketAddr & addr,IAXFullFrame * frame)3009 inline bool writeSocket(const SocketAddr& addr, IAXFullFrame* frame) 3010 { return !frame || writeSocket(frame->data().data(),frame->data().length(),addr,frame); } 3011 3012 /** 3013 * Read events 3014 */ 3015 void runGetEvents(); 3016 3017 /** 3018 * Removes a transaction from queue. Free the allocated local call number 3019 * Does not delete it 3020 * @param transaction Transaction to remove 3021 */ 3022 void removeTransaction(IAXTransaction* transaction); 3023 3024 /** 3025 * Check if there are any transactions in the engine 3026 * This method is thread safe 3027 * @return True if the engine holds at least 1 transaction 3028 */ 3029 bool haveTransactions(); 3030 3031 /** 3032 * Return the transactions count 3033 * This method is thread safe 3034 * @return Transactions count 3035 */ 3036 u_int32_t transactionCount(); 3037 3038 /** 3039 * Send an INVAL with call numbers set to 0 to a remote peer to keep it alive 3040 * @param addr Address to send to 3041 */ 3042 void keepAlive(const SocketAddr& addr); 3043 3044 /** 3045 * Process a new format received with a full frame 3046 * @param trans Transaction that received the new format 3047 * @param type Media type 3048 * @param format The received format 3049 * @return True if accepted 3050 */ mediaFormatChanged(IAXTransaction * trans,int type,u_int32_t format)3051 virtual bool mediaFormatChanged(IAXTransaction* trans, int type, u_int32_t format) 3052 { return false; } 3053 3054 /** 3055 * Check call token on incoming call requests. 3056 * This method is called by the engine when processing an incoming call request 3057 * @param addr The address from where the call request was received 3058 * @param frame Received frame 3059 * @return True if accepted, false to ignore the call 3060 */ 3061 virtual bool checkCallToken(const SocketAddr& addr, IAXFullFrame& frame); 3062 3063 /** 3064 * Process the initial received format and capability. 3065 * If accepted on exit will set the transaction format and capability 3066 * @param trans Transaction that received the new format 3067 * @param caps Optional codecs to set in transaction before processing 3068 * @param type Media type 3069 * @return True if accepted 3070 */ 3071 bool acceptFormatAndCapability(IAXTransaction* trans, unsigned int* caps = 0, 3072 int type = IAXFormat::Audio); 3073 3074 /** 3075 * Default event handler. event MUST NOT be deleted 3076 * @param event The event to handle 3077 */ 3078 virtual void defaultEventHandler(IAXEvent* event); 3079 3080 /** 3081 * Check if the engine is exiting 3082 * @return True if the engine is exiting 3083 */ exiting()3084 inline bool exiting() const 3085 { return m_exiting; } 3086 3087 /** 3088 * Set the exiting flag 3089 */ 3090 virtual void setExiting(); 3091 3092 /** 3093 * Enable trunking for the given transaction. Allocate a trunk meta frame if needed. 3094 * Trunk data is ignored if a trunk object for transaction remote address already exists 3095 * @param trans Transaction to enable trunking for 3096 * @param params Trunk parameters list, may be 0 3097 * @param prefix Trunk parameters name prefix 3098 */ 3099 void enableTrunking(IAXTransaction* trans, const NamedList* params, 3100 const String& prefix = String::empty()); 3101 3102 /** 3103 * Enable trunking for the given transaction. Allocate a trunk meta frame if needed. 3104 * Trunk data is ignored if a trunk object for transaction remote address already exists 3105 * @param trans Transaction to enable trunking for 3106 * @param data Trunk info to use 3107 */ 3108 void enableTrunking(IAXTransaction* trans, IAXTrunkInfo& data); 3109 3110 /** 3111 * Init incoming trunking data for a given transaction 3112 * @param trans Transaction to init 3113 * @param params Trunk parameters list, may be 0 3114 * @param prefix Trunk parameters name prefix 3115 */ 3116 void initTrunkIn(IAXTransaction* trans, const NamedList* params, 3117 const String& prefix = String::empty()); 3118 3119 /** 3120 * Init incoming trunking data for a given transaction 3121 * @param trans Transaction to init 3122 * @param data Trunk info to use 3123 */ 3124 void initTrunkIn(IAXTransaction* trans, IAXTrunkInfo& data); 3125 3126 /** 3127 * Retrieve the default trunk info data 3128 * @param info Destination to be set with trunk info pointer 3129 * @return True if destination pointr is valid 3130 */ trunkInfo(RefPointer<IAXTrunkInfo> & info)3131 inline bool trunkInfo(RefPointer<IAXTrunkInfo>& info) { 3132 Lock lck(m_trunkInfoMutex); 3133 info = m_trunkInfoDef; 3134 return info != 0; 3135 } 3136 3137 /** 3138 * Send an INVAL frame 3139 * @param frame Frame for which to send an INVAL frame 3140 * @param addr The address from where the call request was received 3141 */ 3142 void sendInval(IAXFullFrame* frame, const SocketAddr& addr); 3143 3144 /** 3145 * Keep calling processTrunkFrames to send trunked media data 3146 */ 3147 void runProcessTrunkFrames(); 3148 3149 /** 3150 * Get the socket used for engine operation 3151 * @return Reference to the UDP socket 3152 */ socket()3153 inline Socket& socket() 3154 { return m_socket; } 3155 3156 /** 3157 * Retrieve the socket address on wgich we are bound 3158 * @return Local address we are bound on 3159 */ addr()3160 inline const SocketAddr& addr() const 3161 { return m_addr; } 3162 3163 /** 3164 * Send engine formats 3165 * @param caps Capabilities 3166 * @param fmtAudio Default audio format 3167 * @param fmtVideo Default video format 3168 */ setFormats(u_int32_t caps,u_int32_t fmtAudio,u_int32_t fmtVideo)3169 inline void setFormats(u_int32_t caps, u_int32_t fmtAudio, u_int32_t fmtVideo) { 3170 m_format = fmtAudio; 3171 m_formatVideo = fmtVideo; 3172 m_capability = caps; 3173 } 3174 3175 /** 3176 * Retrieve a port parameter 3177 * @param params Parameters list 3178 * @param param Parameter to retrieve 3179 * @return The port (default, 4569, if the parameter is missing or invalid) 3180 */ 3181 static inline int getPort(const NamedList& params, const String& param = "port") 3182 { return params.getIntValue(param,4569); } 3183 3184 /** 3185 * Get the MD5 data from a challenge and a password 3186 * @param md5data Destination String 3187 * @param challenge Challenge source 3188 * @param password Password source 3189 */ 3190 static void getMD5FromChallenge(String& md5data, const String& challenge, const String& password); 3191 3192 /** 3193 * Test if a received response to an authentication request is correct 3194 * @param md5data Data to compare with 3195 * @param challenge Received challenge 3196 * @param password Password source 3197 */ 3198 static bool isMD5ChallengeCorrect(const String& md5data, const String& challenge, const String& password); 3199 3200 /** 3201 * Build a time signed secret used to authenticate an IP address 3202 * @param buf Destination buffer 3203 * @param secret Extra secret to add to MD5 sum 3204 * @param addr Socket address 3205 */ 3206 static void buildAddrSecret(String& buf, const String& secret, 3207 const SocketAddr& addr); 3208 3209 /** 3210 * Decode a secret built using buildAddrSecret() 3211 * @param buf Input buffer 3212 * @param secret Extra secret to check 3213 * @param addr Socket address 3214 * @return Secret age, negative if invalid 3215 */ 3216 static int addrSecretAge(const String& buf, const String& secret, 3217 const SocketAddr& addr); 3218 3219 /** 3220 * Add string (keyword) if found in a dictionary or integer parameter to a named list 3221 * @param list Destination list 3222 * @param param Parameter to add to the list 3223 * @param tokens The dictionary used to find the given value 3224 * @param val The value to find/add to the list 3225 */ addKeyword(NamedList & list,const char * param,const TokenDict * tokens,unsigned int val)3226 static inline void addKeyword(NamedList& list, const char* param, 3227 const TokenDict* tokens, unsigned int val) { 3228 const char* value = lookup(val,tokens); 3229 if (value) 3230 list.addParam(param,value); 3231 else 3232 list.addParam(param,String(val)); 3233 } 3234 3235 /** 3236 * Decode a DATETIME value 3237 * @param dt Value to decode 3238 * @param year The year component of the date 3239 * @param month The month component of the date 3240 * @param day The day component of the date 3241 * @param hour The hour component of the time 3242 * @param minute The minute component of the time 3243 * @param sec The seconds component of the time 3244 */ 3245 static void decodeDateTime(u_int32_t dt, unsigned int& year, unsigned int& month, 3246 unsigned int& day, unsigned int& hour, unsigned int& minute, unsigned int& sec); 3247 3248 /** 3249 * Calculate overall timeout from interval and retransmission counter 3250 * @param interval The first retransmisssion interval 3251 * @param nRetrans The number of retransmissions 3252 * @return The overall timeout 3253 */ 3254 static unsigned int overallTout(unsigned int interval = IAX2_RETRANS_INTERVAL_DEF, 3255 unsigned int nRetrans = IAX2_RETRANS_COUNT_DEF); 3256 3257 protected: 3258 /** 3259 * Process all trunk meta frames in the queue 3260 * @param time Time of the call 3261 * @return True if at least one frame was sent 3262 */ 3263 bool processTrunkFrames(const Time& time = Time()); 3264 3265 /** 3266 * Default event for connection transactions handler. This method may be overriden to perform custom 3267 * processing 3268 * This method is thread safe 3269 * @param event Event to process 3270 */ 3271 virtual void processEvent(IAXEvent* event); 3272 3273 /** 3274 * Get an IAX event from the queue. 3275 * This method is thread safe. 3276 * @param now Current time 3277 * @return Pointer to an IAXEvent or 0 if none is available 3278 */ 3279 IAXEvent* getEvent(const Time& now = Time()); 3280 3281 /** 3282 * Generate call number. Update used call numbers list 3283 * @return Call number or 0 if none available 3284 */ 3285 u_int16_t generateCallNo(); 3286 3287 /** 3288 * Release a call number 3289 * @param lcallno Call number to release 3290 */ 3291 void releaseCallNo(u_int16_t lcallno); 3292 3293 /** 3294 * Start a transaction based on a local request 3295 * @param type Transaction type 3296 * @param addr Remote address to send the request 3297 * @param ieList First frame IE list 3298 * @param refTrans Return a refferenced transaction pointer 3299 * @param startTrans Start transaction 3300 * @return IAXTransaction pointer on success 3301 */ 3302 IAXTransaction* startLocalTransaction(IAXTransaction::Type type, 3303 const SocketAddr& addr, IAXIEList& ieList, 3304 bool refTrans = false, bool startTrans = true); 3305 3306 /** 3307 * Bind the socket. Terminate it before trying 3308 * @param iface Address of the interface to use, default all (0.0.0.0) 3309 * @param port UDP port to run the protocol on 3310 * @param force Force binding if failed on required port 3311 * @return True on success 3312 */ 3313 bool bind(const char* iface, int port, bool force); 3314 3315 int m_trunking; // Trunking capability: negative: ok, otherwise: not enabled 3316 3317 private: 3318 String m_name; // Engine name 3319 Socket m_socket; // Socket 3320 SocketAddr m_addr; // Address we are bound on 3321 ObjList** m_transList; // Full transactions 3322 ObjList m_incompleteTransList; // Incomplete transactions (no remote call number) 3323 bool m_lUsedCallNo[IAX2_MAX_CALLNO + 1]; // Used local call numnmbers flags 3324 int m_lastGetEvIndex; // getEvent: keep last array entry 3325 bool m_exiting; // Exiting flag 3326 // Parameters 3327 int m_maxFullFrameDataLen; // Max full frame data (IE list) length 3328 u_int16_t m_startLocalCallNo; // Start index of local call number allocation 3329 u_int16_t m_transListCount; // m_transList count 3330 unsigned int m_challengeTout; // Sent challenge timeout interval 3331 bool m_callToken; // Call token required on incoming calls 3332 String m_callTokenSecret; // Secret used to generate call tokens 3333 int m_callTokenAge; // Max allowed call token age 3334 bool m_showCallTokenFailures; // Print incoming call token failures to output 3335 bool m_rejectMissingCallToken; // Reject/ignore incoming calls without call token if mandatory 3336 bool m_printMsg; // Print frame to output 3337 u_int8_t m_callerNumType; // Caller number type 3338 u_int8_t m_callingPres; // Caller presentation + screening 3339 // Media 3340 u_int32_t m_format; // The default media format 3341 u_int32_t m_formatVideo; // Default video format 3342 u_int32_t m_capability; // The media capability 3343 unsigned int m_adjustTsOutThreshold; // Adjust outgoing data timestamp threshold 3344 unsigned int m_adjustTsOutOverrun; // Value used to adjust outgoing data timestamp on data 3345 // overrun (incoming data with rate greater then expected) 3346 unsigned int m_adjustTsOutUnderrun; // Value used to adjust outgoing data timestamp on data 3347 // underrun (incoming data with rate less then expected) 3348 // Trunking 3349 Mutex m_mutexTrunk; // Mutex for trunk operations 3350 ObjList m_trunkList; // Trunk frames list 3351 Mutex m_trunkInfoMutex; // Trunk info mutex 3352 RefPointer<IAXTrunkInfo> m_trunkInfoDef; // Defaults for trunk data 3353 }; 3354 3355 } 3356 3357 #endif /* __YATEIAX_H */ 3358 3359 /* vi: set ts=8 sw=4 sts=4 noet: */ 3360