Yate
|
00001 00024 #ifndef __YATEIAX_H 00025 #define __YATEIAX_H 00026 00027 #include <yateclass.h> 00028 00029 #ifdef _WINDOWS 00030 00031 #ifdef LIBYIAX_EXPORTS 00032 #define YIAX_API __declspec(dllexport) 00033 #else 00034 #ifndef LIBYIAX_STATIC 00035 #define YIAX_API __declspec(dllimport) 00036 #endif 00037 #endif 00038 00039 #endif /* _WINDOWS */ 00040 00041 #ifndef YIAX_API 00042 #define YIAX_API 00043 #endif 00044 00048 namespace TelEngine { 00049 00050 class IAXInfoElement; 00051 class IAXInfoElementString; 00052 class IAXInfoElementNumeric; 00053 class IAXInfoElementBinary; 00054 class IAXFrame; 00055 class IAXFullFrame; 00056 class IAXFrameOut; 00057 class IAXEvent; 00058 class IAXEngine; 00059 00060 #define IAX_PROTOCOL_VERSION 0x0002 // Protocol version 00061 #define IAX2_MAX_CALLNO 32767 // Max call number value 00062 #define IAX2_MAX_TRANSINFRAMELIST 127 // Max transaction incoming frame list 00063 00068 class YIAX_API IAXInfoElement : public RefObject 00069 { 00070 public: 00074 enum Type { 00075 textframe = 0x00, // Text Used internally only to generate an event of type Text 00076 CALLED_NUMBER = 0x01, // Text 00077 CALLING_NUMBER = 0x02, // Text 00078 CALLING_ANI = 0x03, // Text 00079 CALLING_NAME = 0x04, // Text 00080 CALLED_CONTEXT = 0x05, // Text 00081 USERNAME = 0x06, // Text 00082 PASSWORD = 0x07, // Text 00083 CAPABILITY = 0x08, // DW 00084 FORMAT = 0x09, // DW 00085 LANGUAGE = 0x0a, // Text 00086 VERSION = 0x0b, // W Value: IAX_PROTOCOL_VERSION 00087 ADSICPE = 0x0c, // W 00088 DNID = 0x0d, // Text 00089 AUTHMETHODS = 0x0e, // W 00090 CHALLENGE = 0x0f, // Text 00091 MD5_RESULT = 0x10, // Text 00092 RSA_RESULT = 0x11, // Text 00093 APPARENT_ADDR = 0x12, // BIN 00094 REFRESH = 0x13, // W 00095 DPSTATUS = 0x14, // W 00096 CALLNO = 0x15, // W Max value: IAX2_MAX_CALLNO 00097 CAUSE = 0x16, // Text 00098 IAX_UNKNOWN = 0x17, // B 00099 MSGCOUNT = 0x18, // W 00100 AUTOANSWER = 0x19, // Null 00101 MUSICONHOLD = 0x1a, // Text 00102 TRANSFERID = 0x1b, // DW 00103 RDNIS = 0x1c, // Text 00104 PROVISIONING = 0x1d, // BIN 00105 AESPROVISIONING = 0x1e, // BIN 00106 DATETIME = 0x1f, // DW 00107 DEVICETYPE = 0x20, // Text 00108 SERVICEIDENT = 0x21, // BIN 00109 FIRMWAREVER = 0x22, // W 00110 FWBLOCKDESC = 0x23, // DW 00111 FWBLOCKDATA = 0x24, // BIN 00112 PROVVER = 0x25, // DW 00113 CALLINGPRES = 0x26, // B 00114 CALLINGTON = 0x27, // B 00115 CALLINGTNS = 0x28, // W 00116 SAMPLINGRATE = 0x29, // DW 00117 CAUSECODE = 0x2a, // B 00118 ENCRYPTION = 0x2b, // B 00119 ENKEY = 0x2c, // BIN 00120 CODEC_PREFS = 0x2d, // Text 00121 RR_JITTER = 0x2e, // DW 00122 RR_LOSS = 0x2f, // DW 00123 RR_PKTS = 0x30, // DW 00124 RR_DELAY = 0x31, // W 00125 RR_DROPPED = 0x32, // DW 00126 RR_OOO = 0x33, // DW 00127 CALLTOKEN = 0X36, // BIN 00128 }; 00129 00134 inline IAXInfoElement(Type type) : m_type(type) {} 00135 00139 virtual ~IAXInfoElement() {} 00140 00145 inline Type type() const 00146 { return m_type; } 00147 00152 virtual void toBuffer(DataBlock& buf); 00153 00158 virtual void toString(String& buf); 00159 00165 static inline const char* ieText(u_int8_t ieCode) 00166 { return lookup(ieCode,s_ieData); } 00167 00168 00169 private: 00170 static TokenDict s_ieData[];// Association between IE type and text 00171 Type m_type; // Type of this IE 00172 }; 00173 00178 class YIAX_API IAXInfoElementString : public IAXInfoElement 00179 { 00180 public: 00187 inline IAXInfoElementString(Type type, const char* buf, unsigned len) : IAXInfoElement(type), m_strData(buf,(int)len) 00188 {} 00189 00193 virtual ~IAXInfoElementString() {} 00194 00199 inline int length() const 00200 { return m_strData.length(); } 00201 00206 inline String& data() 00207 { return m_strData; } 00208 00213 virtual void toBuffer(DataBlock& buf); 00214 00219 virtual void toString(String& buf) 00220 { buf << m_strData; } 00221 00222 private: 00223 String m_strData; // IE text data 00224 }; 00225 00230 class IAXInfoElementNumeric : public IAXInfoElement 00231 { 00232 public: 00239 IAXInfoElementNumeric(Type type, u_int32_t val, u_int8_t len); 00240 00244 virtual ~IAXInfoElementNumeric() {} 00245 00250 inline int length() const 00251 { return m_length; } 00252 00257 inline u_int32_t data() const 00258 { return m_numericData; } 00259 00264 virtual void toBuffer(DataBlock& buf); 00265 00270 virtual void toString(String& buf); 00271 00272 private: 00273 u_int8_t m_length; // IE data length 00274 u_int32_t m_numericData; // IE numeric data 00275 }; 00276 00281 class YIAX_API IAXInfoElementBinary : public IAXInfoElement 00282 { 00283 public: 00290 IAXInfoElementBinary(Type type, unsigned char* buf, unsigned len) : IAXInfoElement(type), m_data(buf,len) 00291 {} 00292 00296 virtual ~IAXInfoElementBinary() {} 00297 00302 inline int length() const 00303 { return m_data.length(); } 00304 00309 inline DataBlock& data() 00310 { return m_data; } 00311 00317 inline void setData(void* buf, unsigned len) 00318 { m_data.assign(buf,len); } 00319 00324 virtual void toBuffer(DataBlock& buf); 00325 00331 static IAXInfoElementBinary* packIP(const SocketAddr& addr); 00332 00339 static bool unpackIP(SocketAddr& addr, IAXInfoElementBinary* ie); 00340 00345 virtual void toString(String& buf); 00346 00347 private: 00348 DataBlock m_data; // IE binary data 00349 }; 00350 00355 class YIAX_API IAXIEList 00356 { 00357 public: 00361 IAXIEList(); 00362 00368 IAXIEList(const IAXFullFrame* frame, bool incoming = true); 00369 00373 ~IAXIEList(); 00374 00379 inline bool invalidIEList() const 00380 { return m_invalidIEList; } 00381 00385 inline void clear() 00386 { m_list.clear(); } 00387 00392 inline bool empty() 00393 { return 0 == m_list.skipNull(); } 00394 00398 void insertVersion(); 00399 00404 inline bool validVersion() { 00405 u_int32_t ver = 0xFFFF; 00406 getNumeric(IAXInfoElement::VERSION,ver); 00407 return ver == IAX_PROTOCOL_VERSION; 00408 } 00409 00414 inline void appendIE(IAXInfoElement* ie) 00415 { m_list.append(ie); } 00416 00421 inline void appendNull(IAXInfoElement::Type type) 00422 { m_list.append(new IAXInfoElement(type)); } 00423 00429 inline void appendString(IAXInfoElement::Type type, const String& src) 00430 { m_list.append(new IAXInfoElementString(type,src.c_str(),src.length())); } 00431 00438 inline void appendString(IAXInfoElement::Type type, unsigned char* src, unsigned len) 00439 { m_list.append(new IAXInfoElementString(type,(char*)src,len)); } 00440 00447 inline void appendNumeric(IAXInfoElement::Type type, u_int32_t value, u_int8_t len) 00448 { m_list.append(new IAXInfoElementNumeric(type,value,len)); } 00449 00456 inline void appendBinary(IAXInfoElement::Type type, unsigned char* data, unsigned len) 00457 { m_list.append(new IAXInfoElementBinary(type,data,len)); } 00458 00466 bool createFromFrame(const IAXFullFrame* frame, bool incoming = true); 00467 00472 void toBuffer(DataBlock& buf); 00473 00479 void toString(String& dest, const char* indent = 0); 00480 00486 IAXInfoElement* getIE(IAXInfoElement::Type type); 00487 00494 bool getString(IAXInfoElement::Type type, String& dest); 00495 00502 bool getNumeric(IAXInfoElement::Type type, u_int32_t& dest); 00503 00510 bool getBinary(IAXInfoElement::Type type, DataBlock& dest); 00511 00512 private: 00513 bool m_invalidIEList; // Invalid IE flag 00514 ObjList m_list; // The IE list 00515 }; 00516 00521 class YIAX_API IAXAuthMethod 00522 { 00523 public: 00527 enum Type { 00528 Text = 1, 00529 MD5 = 2, 00530 RSA = 4, 00531 }; 00532 00539 static void authList(String& dest, u_int16_t auth, char sep); 00540 00541 static TokenDict s_texts[]; 00542 }; 00543 00548 class YIAX_API IAXFormat 00549 { 00550 public: 00554 enum Formats { 00555 G723_1 = (1 << 0), 00556 GSM = (1 << 1), 00557 ULAW = (1 << 2), 00558 ALAW = (1 << 3), 00559 G726 = (1 << 4), 00560 ADPCM = (1 << 5), 00561 SLIN = (1 << 6), 00562 LPC10 = (1 << 7), 00563 G729 = (1 << 8), 00564 SPEEX = (1 << 9), 00565 ILBC = (1 << 10), 00566 G726AAL2 = (1 << 11), 00567 G722 = (1 << 12), 00568 AMR = (1 << 13), 00569 AudioMask = G723_1 | GSM | ULAW | ALAW | G726 | ADPCM | SLIN | LPC10 | G729 | SPEEX | 00570 ILBC | G726AAL2 | G722 | AMR, 00571 JPEG = (1 << 16), 00572 PNG = (1 << 17), 00573 ImageMask = JPEG | PNG, 00574 H261 = (1 << 18), 00575 H263 = (1 << 19), 00576 H263p = (1 << 20), 00577 H264 = (1 << 21), 00578 VideoMask = H261 | H263 | H263p | H264, 00579 }; 00580 00584 enum Media { 00585 Audio = 0, 00586 Video, 00587 Image, 00588 TypeCount 00589 }; 00590 00595 inline IAXFormat(int type = Audio) 00596 : m_type(type), m_format(0), m_formatIn(0), m_formatOut(0) 00597 {} 00598 00603 inline int type() const 00604 { return m_type; } 00605 00610 inline u_int32_t format() const 00611 { return m_format; } 00612 00617 inline u_int32_t in() const 00618 { return m_formatIn; } 00619 00624 inline u_int32_t out() const 00625 { return m_formatOut; } 00626 00631 inline const char* formatName() const 00632 { return formatName(m_format); } 00633 00638 inline const char* typeName() const 00639 { return typeName(m_type); } 00640 00647 void set(u_int32_t* fmt, u_int32_t* fmtIn, u_int32_t* fmtOut); 00648 00656 static void formatList(String& dest, u_int32_t formats, const TokenDict* dict = 0, 00657 const char* sep = ","); 00658 00665 static u_int32_t pickFormat(u_int32_t formats, u_int32_t format = 0); 00666 00674 static u_int32_t encode(const String& formats, const TokenDict* dict, char sep = ','); 00675 00682 static inline u_int32_t mask(u_int32_t value, int type) { 00683 if (type == Audio) 00684 return value & AudioMask; 00685 if (type == Video) 00686 return value & VideoMask; 00687 if (type == Image) 00688 return value & ImageMask; 00689 return 0; 00690 } 00691 00698 static inline u_int32_t clear(u_int32_t value, int type) { 00699 if (type == Audio) 00700 return value & ~AudioMask; 00701 if (type == Video) 00702 return value & ~VideoMask; 00703 if (type == Image) 00704 return value & ~ImageMask; 00705 return value; 00706 } 00707 00713 static inline const char* formatName(u_int32_t fmt) 00714 { return lookup(fmt,s_formats); } 00715 00721 static inline const char* typeName(int type) 00722 { return lookup(type,s_types); } 00723 00727 static const TokenDict s_formats[]; 00728 00732 static const TokenDict s_types[]; 00733 00734 protected: 00735 int m_type; 00736 u_int32_t m_format; 00737 u_int32_t m_formatIn; 00738 u_int32_t m_formatOut; 00739 }; 00740 00745 class YIAX_API IAXControl 00746 { 00747 public: 00751 enum Type { 00752 New = 0x01, 00753 Ping = 0x02, 00754 Pong = 0x03, 00755 Ack = 0x04, 00756 Hangup = 0x05, 00757 Reject = 0x06, 00758 Accept = 0x07, 00759 AuthReq = 0x08, 00760 AuthRep = 0x09, 00761 Inval = 0x0a, 00762 LagRq = 0x0b, 00763 LagRp = 0x0c, 00764 RegReq = 0x0d, 00765 RegAuth = 0x0e, 00766 RegAck = 0x0f, 00767 RegRej = 0x10, 00768 RegRel = 0x11, 00769 VNAK = 0x12, 00770 DpReq = 0x13, 00771 DpRep = 0x14, 00772 Dial = 0x15, 00773 TxReq = 0x16, 00774 TxCnt = 0x17, 00775 TxAcc = 0x18, 00776 TxReady = 0x19, 00777 TxRel = 0x1a, 00778 TxRej = 0x1b, 00779 Quelch = 0x1c, 00780 Unquelch = 0x1d, 00781 Poke = 0x1e, 00782 //Reserved = 0x1f, 00783 MWI = 0x20, 00784 Unsupport = 0x21, 00785 Transfer = 0x22, 00786 Provision = 0x23, 00787 FwDownl = 0x24, 00788 FwData = 0x25, 00789 CallToken = 0x28, 00790 }; 00791 00797 static inline const char* typeText(int type) 00798 { return lookup(type,s_types,0); } 00799 00800 private: 00801 static TokenDict s_types[]; // Keep the association between IAX control codes and their name 00802 }; 00803 00808 class YIAX_API IAXFrame : public RefObject 00809 { 00810 public: 00814 enum Type { 00815 DTMF = 0x01, 00816 Voice = 0x02, 00817 Video = 0x03, 00818 Control = 0x04, 00819 Null = 0x05, 00820 IAX = 0x06, 00821 Text = 0x07, 00822 Image = 0x08, 00823 HTML = 0x09, 00824 Noise = 0x0a, 00825 }; 00826 00837 IAXFrame(Type type, u_int16_t sCallNo, u_int32_t tStamp, bool retrans, 00838 const unsigned char* buf, unsigned int len, bool mark = false); 00839 00843 virtual ~IAXFrame(); 00844 00849 inline Type type() const 00850 { return m_type; } 00851 00856 inline DataBlock& data() 00857 { return m_data; } 00858 00863 inline bool retrans() const 00864 { return m_retrans; } 00865 00870 inline u_int16_t sourceCallNo() const 00871 { return m_sCallNo; } 00872 00877 inline u_int32_t timeStamp() const 00878 { return m_tStamp; } 00879 00884 inline bool mark() const 00885 { return m_mark; } 00886 00891 virtual IAXFullFrame* fullFrame(); 00892 00901 static IAXFrame* parse(const unsigned char* buf, unsigned int len, IAXEngine* engine = 0, const SocketAddr* addr = 0); 00902 00911 static void buildMiniFrame(DataBlock& dest, u_int16_t sCallNo, u_int32_t tStamp, 00912 void* data, unsigned int len); 00913 00923 static void buildVideoMetaFrame(DataBlock& dest, u_int16_t sCallNo, u_int32_t tStamp, 00924 bool mark, void* data, unsigned int len); 00925 00931 static u_int8_t packSubclass(u_int32_t value); 00932 00938 static u_int32_t unpackSubclass(u_int8_t value); 00939 00945 static inline const char* typeText(int type) 00946 { return lookup(type,s_types,0); } 00947 00948 protected: 00952 DataBlock m_data; 00953 00957 bool m_retrans; 00958 00959 private: 00960 static TokenDict s_types[]; // Keep the association between IAX frame types and their names 00961 Type m_type; // Frame type 00962 u_int16_t m_sCallNo; // Source call number 00963 u_int32_t m_tStamp; // Frame timestamp 00964 bool m_mark; // Mark flag 00965 }; 00966 00971 class YIAX_API IAXFullFrame : public IAXFrame 00972 { 00973 public: 00977 enum ControlType { 00978 Hangup = 0x01, 00979 //Ring = 0x02, 00980 Ringing = 0x03, 00981 Answer = 0x04, 00982 Busy = 0x05, 00983 Congestion = 0x08, 00984 FlashHook = 0x09, 00985 Option = 0x0b, 00986 KeyRadio = 0x0c, 00987 UnkeyRadio = 0x0d, 00988 Progressing = 0x0e, 00989 Proceeding = 0x0f, 00990 Hold = 0x10, 00991 Unhold = 0x11, 00992 VidUpdate = 0x12, 00993 }; 00994 01009 IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 01010 unsigned char oSeqNo, unsigned char iSeqNo, 01011 u_int32_t tStamp, bool retrans, 01012 const unsigned char* buf, unsigned int len, bool mark = false); 01013 01027 IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 01028 unsigned char oSeqNo, unsigned char iSeqNo, 01029 u_int32_t tStamp, 01030 const unsigned char* buf = 0, unsigned int len = 0, bool mark = false); 01031 01045 IAXFullFrame(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 01046 unsigned char oSeqNo, unsigned char iSeqNo, 01047 u_int32_t tStamp, IAXIEList* ieList, u_int16_t maxlen, bool mark = false); 01048 01052 virtual ~IAXFullFrame(); 01053 01058 inline u_int16_t destCallNo() const 01059 { return m_dCallNo; } 01060 01065 inline unsigned char oSeqNo() const 01066 { return m_oSeqNo; } 01067 01072 inline unsigned char iSeqNo() const 01073 { return m_iSeqNo; } 01074 01079 inline u_int32_t subclass() const 01080 { return m_subclass; } 01081 01086 virtual IAXFullFrame* fullFrame(); 01087 01092 void updateBuffer(u_int16_t maxlen); 01093 01098 inline IAXIEList* ieList() 01099 { return m_ieList; } 01100 01106 bool updateIEList(bool incoming); 01107 01113 IAXIEList* removeIEList(bool delObj = true); 01114 01122 void toString(String& dest, const SocketAddr& local, const SocketAddr& remote, 01123 bool incoming); 01124 01130 static inline const char* controlTypeText(int type) 01131 { return lookup(type,s_controlTypes,0); } 01132 01133 protected: 01137 virtual void destroyed(); 01138 01139 private: 01140 // Build frame buffer header 01141 void setDataHeader(); 01142 static TokenDict s_controlTypes[]; // Keep the association between control types and their names 01143 u_int16_t m_dCallNo; // Destination call number 01144 unsigned char m_oSeqNo; // Out sequence number 01145 unsigned char m_iSeqNo; // In sequence number 01146 u_int32_t m_subclass; // Subclass 01147 IAXIEList* m_ieList; // List of IEs 01148 }; 01149 01154 class YIAX_API IAXFrameOut : public IAXFullFrame 01155 { 01156 public: 01173 inline IAXFrameOut(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 01174 unsigned char oSeqNo, unsigned char iSeqNo, u_int32_t tStamp, const unsigned char* buf, unsigned int len, 01175 u_int16_t retransCount, u_int32_t retransInterval, bool ackOnly, bool mark = false) 01176 : IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,buf,len,mark), 01177 m_ack(false), m_ackOnly(ackOnly), m_retransCount(retransCount), m_retransTimeInterval(retransInterval), 01178 m_nextTransTime(Time::msecNow() + m_retransTimeInterval) 01179 {} 01180 01197 inline IAXFrameOut(Type type, u_int32_t subclass, u_int16_t sCallNo, u_int16_t dCallNo, 01198 unsigned char oSeqNo, unsigned char iSeqNo, u_int32_t tStamp, 01199 IAXIEList* ieList, u_int16_t maxlen, 01200 u_int16_t retransCount, u_int32_t retransInterval, bool ackOnly, bool mark = false) 01201 : IAXFullFrame(type,subclass,sCallNo,dCallNo,oSeqNo,iSeqNo,tStamp,ieList,maxlen,mark), 01202 m_ack(false), m_ackOnly(ackOnly), m_retransCount(retransCount), m_retransTimeInterval(retransInterval), 01203 m_nextTransTime(Time::msecNow() + m_retransTimeInterval) 01204 {} 01205 01209 virtual ~IAXFrameOut() 01210 {} 01211 01216 inline bool timeout() const 01217 { return m_retransCount == 0; } 01218 01224 inline bool timeForRetrans(u_int64_t time) const 01225 { return time > m_nextTransTime; } 01226 01230 void setRetrans(); 01231 01235 void transmitted(); 01236 01241 inline bool ack() const 01242 { return m_ack; } 01243 01247 inline void setAck() 01248 { m_ack = true; } 01249 01254 inline bool ackOnly() const 01255 { return m_ackOnly; } 01256 01261 void adjustAuthTimeout(u_int64_t nextTransTime); 01262 01263 private: 01264 bool m_ack; // Acknoledge flag 01265 bool m_ackOnly; // Frame need only ACK as a response 01266 u_int16_t m_retransCount; // Retransmission counter 01267 u_int32_t m_retransTimeInterval; // Retransmission interval 01268 u_int64_t m_nextTransTime; // Next transmission time 01269 }; 01270 01275 class YIAX_API IAXMetaTrunkFrame : public RefObject, public Mutex 01276 { 01277 public: 01283 IAXMetaTrunkFrame(IAXEngine* engine, const SocketAddr& addr); 01284 01288 virtual ~IAXMetaTrunkFrame(); 01289 01294 inline const SocketAddr& addr() const 01295 { return m_addr; } 01296 01301 inline u_int32_t timestamp() 01302 { return m_timestamp; } 01303 01308 void setTimestamp(u_int32_t tStamp); 01309 01317 bool add(u_int16_t sCallNo, const DataBlock& data, u_int32_t tStamp); 01318 01324 bool send(u_int32_t tStamp = Time::msecNow()); 01325 01326 private: 01327 u_int8_t* m_data; // Data buffer 01328 u_int16_t m_dataAddIdx; // Current add index 01329 u_int32_t m_timestamp; // Frame timestamp 01330 IAXEngine* m_engine; // The engine that owns this frame 01331 SocketAddr m_addr; // Remote peer address 01332 }; 01333 01339 class YIAX_API IAXMediaData : public Mutex 01340 { 01341 friend class IAXTransaction; 01342 public: 01346 inline IAXMediaData() 01347 : Mutex(true,"IAXTransaction::InMedia"), 01348 m_lastOut(0), m_lastIn(0), m_sent(0), m_sentBytes(0), 01349 m_recv(0), m_recvBytes(0), m_ooPackets(0), m_ooBytes(0), 01350 m_showInNoFmt(true) 01351 {} 01352 01357 void print(String& buf); 01358 01359 protected: 01360 u_int32_t m_lastOut; // Last transmitted mini timestamp 01361 u_int32_t m_lastIn; // Last received timestamp 01362 unsigned int m_sent; // Packets sent 01363 unsigned int m_sentBytes; // Bytes sent 01364 unsigned int m_recv; // Packets received 01365 unsigned int m_recvBytes; // Bytes received 01366 unsigned int m_ooPackets; // Dropped received out of order packets 01367 unsigned int m_ooBytes; // Dropped received out of order bytes 01368 bool m_showInNoFmt; // Show incoming media arrival without format debug 01369 }; 01370 01376 class YIAX_API IAXTransaction : public RefObject, public Mutex 01377 { 01378 friend class IAXEvent; 01379 friend class IAXEngine; 01380 public: 01384 enum Type { 01385 Incorrect, // Unsupported/unknown type 01386 New, // Media exchange call 01387 RegReq, // Registration 01388 RegRel, // Registration release 01389 Poke, // Ping 01390 //FwDownl, 01391 }; 01392 01396 enum State { 01397 Connected, // Call leg established (Accepted) for transactions of type New 01398 NewLocalInvite, // New outgoing transaction: Poke/New/RegReq/RegRel 01399 NewLocalInvite_AuthRecv, // Auth request received for an outgoing transaction 01400 NewLocalInvite_RepSent, // Auth reply sent for an outgoing transaction 01401 NewRemoteInvite, // New incoming transaction: Poke/New/RegReq/RegRel 01402 NewRemoteInvite_AuthSent, // Auth sent for an incoming transaction 01403 NewRemoteInvite_RepRecv, // Auth reply received for an incoming transaction 01404 Unknown, // Initial state 01405 Terminated, // Terminated. No more frames accepted 01406 Terminating, // Terminating. Wait for ACK or timeout to terminate 01407 }; 01408 01418 static IAXTransaction* factoryIn(IAXEngine* engine, IAXFullFrame* frame, u_int16_t lcallno, const SocketAddr& addr, 01419 void* data = 0); 01420 01430 static IAXTransaction* factoryOut(IAXEngine* engine, Type type, u_int16_t lcallno, const SocketAddr& addr, 01431 IAXIEList& ieList, void* data = 0); 01432 01436 virtual ~IAXTransaction(); 01437 01442 inline IAXEngine* getEngine() const 01443 { return m_engine; } 01444 01449 inline Type type() const 01450 { return m_type; } 01451 01456 inline State state() const 01457 { return m_state; } 01458 01463 inline u_int64_t timeStamp() const 01464 { return Time::msecNow() - m_timeStamp; } 01465 01470 inline bool outgoing() const 01471 { return m_localInitTrans; } 01472 01477 inline void setUserData(void* data) 01478 { m_userdata = data; } 01479 01484 inline void* getUserData() const 01485 { return m_userdata; } 01486 01491 inline u_int16_t localCallNo() const 01492 { return m_lCallNo; } 01493 01498 inline u_int16_t remoteCallNo() const 01499 { return m_rCallNo; } 01500 01505 inline const SocketAddr& remoteAddr() const 01506 { return m_addr; } 01507 01512 inline const String& username() 01513 { return m_username; } 01514 01519 inline const String& callingNo() 01520 { return m_callingNo; } 01521 01526 inline const String& callingName() 01527 { return m_callingName; } 01528 01533 inline const String& calledNo() 01534 { return m_calledNo; } 01535 01540 inline const String& calledContext() 01541 { return m_calledContext; } 01542 01547 inline const String& challenge() 01548 { return m_challenge; } 01549 01555 IAXFormat* getFormat(int type); 01556 01562 IAXMediaData* getData(int type); 01563 01569 inline u_int32_t format(int type) { 01570 IAXFormat* fmt = getFormat(type); 01571 return fmt ? fmt->format() : 0; 01572 } 01573 01579 inline u_int32_t formatIn(int type) { 01580 IAXFormat* fmt = getFormat(type); 01581 return fmt ? fmt->in() : 0; 01582 } 01583 01589 inline u_int32_t formatOut(int type) { 01590 IAXFormat* fmt = getFormat(type); 01591 return fmt ? fmt->out() : 0; 01592 } 01593 01598 inline u_int32_t capability() const 01599 { return m_capability; } 01600 01605 inline u_int32_t expire() const 01606 { return m_expire; } 01607 01612 inline const String& authdata() 01613 { return m_authdata; } 01614 01621 IAXTransaction* processFrame(IAXFrame* frame); 01622 01632 IAXTransaction* processMedia(DataBlock& data, u_int32_t tStamp, 01633 int type = IAXFormat::Audio, bool full = false, bool mark = false); 01634 01643 unsigned int sendMedia(const DataBlock& data, u_int32_t format, 01644 int type = IAXFormat::Audio, bool mark = false); 01645 01652 IAXEvent* getEvent(u_int64_t time); 01653 01658 static unsigned char getMaxFrameList(); 01659 01665 static bool setMaxFrameList(unsigned char value); 01666 01672 inline bool sendAnswer() 01673 { return sendConnected(IAXFullFrame::Answer); } 01674 01680 inline bool sendRinging() 01681 { return sendConnected(IAXFullFrame::Ringing); } 01682 01688 inline bool sendProgress() 01689 { return sendConnected(IAXFullFrame::Proceeding); } 01690 01699 bool sendAccept(unsigned int* expires = 0); 01700 01708 bool sendHangup(const char* cause = 0, u_int8_t code = 0); 01709 01717 bool sendReject(const char* cause = 0, u_int8_t code = 0); 01718 01724 bool sendAuth(); 01725 01732 bool sendAuthReply(const String& response); 01733 01740 inline bool sendDtmf(u_int8_t dtmf) 01741 { return dtmf <= 127 ? sendConnected((IAXFullFrame::ControlType)dtmf,IAXFrame::DTMF) : false; } 01742 01749 bool sendText(const char* text); 01750 01757 inline bool sendNoise(u_int8_t noise) 01758 { return noise <= 127 ? sendConnected((IAXFullFrame::ControlType)noise,IAXFrame::Noise) : false; } 01759 01765 bool abortReg(); 01766 01772 bool enableTrunking(IAXMetaTrunkFrame* trunkFrame); 01773 01779 void processCallToken(const DataBlock& callToken); 01780 01787 void print(bool printStats = false, bool printFrames = false, const char* location = "status"); 01788 01792 static String s_iax_modNoAuthMethod; 01793 01797 static String s_iax_modNoMediaFormat; 01798 01802 static String s_iax_modInvalidAuth; 01803 01807 static String s_iax_modNoUsername; 01808 01809 protected: 01819 IAXTransaction(IAXEngine* engine, IAXFullFrame* frame, u_int16_t lcallno, const SocketAddr& addr, 01820 void* data = 0); 01821 01831 IAXTransaction(IAXEngine* engine, Type type, u_int16_t lcallno, const SocketAddr& addr, IAXIEList& ieList, 01832 void* data = 0); 01833 01837 virtual void destroyed(); 01838 01843 void init(IAXIEList& ieList); 01844 01851 bool incrementSeqNo(const IAXFullFrame* frame, bool inbound); 01852 01858 bool isFrameAcceptable(const IAXFullFrame* frame); 01859 01865 bool changeState(State newState); 01866 01875 IAXEvent* terminate(u_int8_t evType, bool local, IAXFullFrame* frame = 0, bool createIEList = true); 01876 01884 IAXEvent* waitForTerminate(u_int8_t evType, bool local, IAXFullFrame* frame); 01885 01897 void postFrame(IAXFrame::Type type, u_int32_t subclass, void* data = 0, u_int16_t len = 0, u_int32_t tStamp = 0, 01898 bool ackOnly = false, bool mark = false); 01899 01909 void postFrameIes(IAXFrame::Type type, u_int32_t subclass, IAXIEList* ies, u_int32_t tStamp = 0, 01910 bool ackOnly = false); 01911 01918 bool sendFrame(IAXFrameOut* frame, bool vnak = false); 01919 01928 IAXEvent* createEvent(u_int8_t evType, bool local, IAXFullFrame* frame, State newState); 01929 01941 IAXEvent* createResponse(IAXFrameOut* frame, u_int8_t findType, u_int8_t findSubclass, u_int8_t evType, bool local, State newState); 01942 01949 IAXEvent* getEventResponse(IAXFrameOut* frame, bool& delFrame); 01950 01957 IAXEvent* getEventResponse_New(IAXFrameOut* frame, bool& delFrame); 01958 01964 IAXEvent* processAuthReq(IAXEvent* event); 01965 01972 IAXEvent* processAccept(IAXEvent* event); 01973 01979 IAXEvent* processAuthRep(IAXEvent* event); 01980 01987 IAXEvent* getEventResponse_Reg(IAXFrameOut* frame, bool& delFrame); 01988 01994 IAXEvent* processRegAck(IAXEvent* event); 01995 02002 IAXEvent* getEventStartTrans(IAXFullFrame* frame, bool& delFrame); 02003 02010 IAXEvent* getEventRequest(IAXFullFrame* frame, bool& delFrame); 02011 02018 IAXEvent* getEventRequest_New(IAXFullFrame* frame, bool& delFrame); 02019 02026 IAXFullFrame* findInFrame(IAXFrame::Type type, u_int32_t subclass); 02027 02035 bool findInFrameTimestamp(const IAXFullFrame* frameOut, IAXFrame::Type type, u_int32_t subclass); 02036 02042 bool findInFrameAck(const IAXFullFrame* frameOut); 02043 02047 void ackInFrames(); 02048 02056 bool sendConnected(IAXFullFrame::ControlType subclass, IAXFrame::Type frametype = IAXFrame::Control); 02057 02062 void sendAck(const IAXFullFrame* frame); 02063 02067 void sendInval(); 02068 02072 void sendVNAK(); 02073 02078 void sendUnsupport(u_int32_t subclass); 02079 02086 IAXEvent* processInternalOutgoingRequest(IAXFrameOut* frame, bool& delFrame); 02087 02094 IAXEvent* processInternalIncomingRequest(const IAXFullFrame* frame, bool& delFrame); 02095 02102 IAXEvent* processMidCallControl(IAXFullFrame* frame, bool& delFrame); 02103 02110 IAXEvent* processMidCallIAXControl(IAXFullFrame* frame, bool& delFrame); 02111 02118 IAXEvent* remoteRejectCall(IAXFullFrame* frame, bool& delFrame); 02119 02125 IAXEvent* getEventTerminating(u_int64_t time); 02126 02133 IAXTransaction* processMediaFrame(const IAXFullFrame* frame, int type); 02134 02140 IAXTransaction* retransmitOnVNAK(u_int16_t seqNo); 02141 02146 IAXEvent* internalAccept(); 02147 02153 IAXEvent* internalReject(String& reason); 02154 02160 void eventTerminated(IAXEvent* event); 02161 02167 inline IAXEvent* keepEvent(IAXEvent* event) { 02168 m_currentEvent = event; 02169 return event; 02170 } 02171 02172 private: 02173 void adjustTStamp(u_int32_t& tStamp); 02174 void postFrame(IAXFrameOut* frame); 02175 02176 // Params 02177 bool m_localInitTrans; // True: local initiated transaction 02178 bool m_localReqEnd; // Local client requested terminate 02179 Type m_type; // Transaction type 02180 State m_state; // Transaction state 02181 u_int64_t m_timeStamp; // Transaction creation timestamp 02182 u_int32_t m_timeout; // Transaction timeout (in seconds) on remote termination request 02183 SocketAddr m_addr; // Socket 02184 u_int16_t m_lCallNo; // Local peer call id 02185 u_int16_t m_rCallNo; // Remote peer call id 02186 unsigned char m_oSeqNo; // Outgoing frame sequence number 02187 unsigned char m_iSeqNo; // Incoming frame sequence number 02188 IAXEngine* m_engine; // Engine that owns this transaction 02189 void* m_userdata; // Arbitrary user data 02190 u_int32_t m_lastFullFrameOut; // Last transmitted full frame timestamp 02191 IAXMediaData m_dataAudio; 02192 IAXMediaData m_dataVideo; 02193 u_int16_t m_lastAck; // Last ack'd received frame's oseqno 02194 IAXEvent* m_pendingEvent; // Pointer to a pending event or 0 02195 IAXEvent* m_currentEvent; // Pointer to last generated event or 0 02196 // Outgoing frames management 02197 ObjList m_outFrames; // Transaction & protocol control outgoing frames 02198 u_int16_t m_retransCount; // Retransmission counter. 0 --> Timeout 02199 u_int32_t m_retransInterval; // Frame retransmission interval 02200 // Incoming frames management 02201 ObjList m_inFrames; // Transaction & protocol control incoming frames 02202 static unsigned char m_maxInFrames; // Max frames number allowed in m_inFrames 02203 // Call leg management 02204 u_int32_t m_pingInterval; // Ping remote peer interval 02205 u_int64_t m_timeToNextPing; // Time of the next Ping 02206 // Statistics 02207 u_int32_t m_inTotalFramesCount; // Total received frames 02208 u_int32_t m_inOutOfOrderFrames; // Total out of order frames 02209 u_int32_t m_inDroppedFrames; // Total dropped frames 02210 // Data 02211 IAXAuthMethod::Type m_authmethod; // Authentication method to use 02212 String m_username; // Username 02213 String m_callingNo; // Calling number 02214 String m_callingName; // Calling name 02215 String m_calledNo; // Called number 02216 String m_calledContext; // Called context 02217 String m_challenge; // Challenge 02218 String m_authdata; // Auth data received with auth reply 02219 u_int32_t m_expire; // Registration expiring time 02220 IAXFormat m_format; // Audio format 02221 IAXFormat m_formatVideo; // Video format 02222 u_int32_t m_capability; // Media capability of this transaction 02223 bool m_callToken; // Call token supported/expected 02224 // Meta trunking 02225 IAXMetaTrunkFrame* m_trunkFrame; // Reference to a trunk frame if trunking is enabled for this transaction 02226 }; 02227 02232 class YIAX_API IAXEvent 02233 { 02234 friend class IAXTransaction; 02235 friend class IAXConnectionlessTransaction; 02236 public: 02240 enum Type { 02241 Invalid = 0, // Invalid frame received 02242 Terminated, // Transaction terminated 02243 Timeout, // Transaction timeout 02244 NotImplemented, // Feature not implemented 02245 New, // New remote transaction 02246 AuthReq, // Auth request 02247 AuthRep, // Auth reply 02248 Accept, // Request accepted 02249 Hangup, // Remote hangup 02250 Reject, // Remote reject 02251 Busy, // Call busy 02252 Text, // Text frame received 02253 Dtmf, // DTMF frame received 02254 Noise, // Noise frame received 02255 Answer, // Call answered 02256 Quelch, // Quelch the call 02257 Unquelch, // Unquelch the call 02258 Progressing, // Call progressing 02259 Ringing, // Ringing 02260 }; 02261 02266 ~IAXEvent(); 02267 02272 inline Type type() const 02273 { return m_type; } 02274 02279 inline bool local() const 02280 { return m_local; } 02281 02286 inline bool final() const 02287 { return m_final; } 02288 02292 inline void setFinal() 02293 { m_final = true; } 02294 02300 inline u_int8_t frameType() 02301 { return m_frameType; } 02302 02307 inline u_int32_t subclass() 02308 { return m_subClass; } 02309 02314 inline IAXEngine* getEngine() const 02315 { return m_transaction ? m_transaction->getEngine() : 0; } 02316 02321 inline IAXTransaction* getTransaction() const 02322 { return m_transaction; } 02323 02328 inline void* getUserData() const 02329 { return m_transaction ? m_transaction->getUserData() : 0; } 02330 02335 inline IAXIEList& getList() 02336 { return *m_ieList; } 02337 02338 protected: 02348 IAXEvent(Type type, bool local, bool final, IAXTransaction* transaction, u_int8_t frameType = 0, u_int32_t subclass = 0); 02349 02358 IAXEvent(Type type, bool local, bool final, IAXTransaction* transaction, IAXFullFrame* frame = 0); 02359 02360 private: 02361 inline IAXEvent() {} // Default constructor 02362 02363 Type m_type; // Event type 02364 u_int8_t m_frameType; // Frame type 02365 u_int32_t m_subClass; // Frame subclass 02366 bool m_local; // If true the event is generated locally, the receiver MUST not respond 02367 bool m_final; // Final event flag 02368 IAXTransaction* m_transaction; // Transaction that generated this event 02369 IAXIEList* m_ieList; // IAXInfoElement list 02370 }; 02371 02376 class YIAX_API IAXEngine : public DebugEnabler, public Mutex 02377 { 02378 public: 02395 IAXEngine(const char* iface, int port, u_int16_t transListCount, u_int16_t retransCount, u_int16_t retransInterval, 02396 u_int16_t authTimeout, u_int16_t transTimeout, u_int16_t maxFullFrameDataLen, 02397 u_int32_t format, u_int32_t capab, u_int32_t trunkSendInterval, bool authRequired, 02398 NamedList* params = 0); 02399 02404 virtual ~IAXEngine(); 02405 02412 IAXTransaction* addFrame(const SocketAddr& addr, IAXFrame* frame); 02413 02421 IAXTransaction* addFrame(const SocketAddr& addr, const unsigned char* buf, unsigned int len); 02422 02431 virtual void processMedia(IAXTransaction* transaction, DataBlock& data, u_int32_t tStamp, 02432 int type, bool mark) 02433 {} 02434 02440 bool process(); 02441 02446 inline u_int16_t retransCount() const 02447 { return m_retransCount; } 02448 02453 inline u_int16_t retransInterval() const 02454 { return m_retransInterval; } 02455 02460 inline bool authRequired() const 02461 { return m_authRequired; } 02462 02467 inline u_int16_t authTimeout() const 02468 { return m_authTimeout; } 02469 02474 inline u_int32_t transactionTimeout() const 02475 { return m_transTimeout; } 02476 02481 inline u_int16_t maxFullFrameDataLen() const 02482 { return m_maxFullFrameDataLen; } 02483 02489 inline u_int32_t format(bool audio = true) const 02490 { return audio ? m_format : m_formatVideo; } 02491 02496 inline u_int32_t capability() const 02497 { return m_capability; } 02498 02503 void initialize(const NamedList& params); 02504 02509 void readSocket(SocketAddr& addr); 02510 02520 bool writeSocket(const void* buf, int len, const SocketAddr& addr, IAXFullFrame* frame = 0, 02521 unsigned int* sent = 0); 02522 02529 inline bool writeSocket(const SocketAddr& addr, IAXFullFrame* frame) 02530 { return !frame || writeSocket(frame->data().data(),frame->data().length(),addr,frame); } 02531 02535 void runGetEvents(); 02536 02542 void removeTransaction(IAXTransaction* transaction); 02543 02549 u_int32_t transactionCount(); 02550 02555 void keepAlive(SocketAddr& addr); 02556 02564 virtual bool mediaFormatChanged(IAXTransaction* trans, int type, u_int32_t format) 02565 { return false; } 02566 02574 virtual bool checkCallToken(const SocketAddr& addr, IAXFullFrame& frame); 02575 02584 bool acceptFormatAndCapability(IAXTransaction* trans, unsigned int* caps = 0, 02585 int type = IAXFormat::Audio); 02586 02591 virtual void defaultEventHandler(IAXEvent* event); 02592 02597 void enableTrunking(IAXTransaction* trans); 02598 02603 void removeTrunkFrame(IAXMetaTrunkFrame* metaFrame); 02604 02609 inline void sendTrunkFrame(IAXMetaTrunkFrame* metaFrame) { 02610 if (!metaFrame) 02611 return; 02612 Lock lck(m_mutexTrunk); 02613 metaFrame->send(); 02614 } 02615 02619 void runProcessTrunkFrames(); 02620 02625 inline Socket& socket() 02626 { return m_socket; } 02627 02634 inline void setFormats(u_int32_t caps, u_int32_t fmtAudio, u_int32_t fmtVideo) { 02635 m_format = fmtAudio; 02636 m_formatVideo = fmtVideo; 02637 m_capability = caps; 02638 } 02639 02646 static void getMD5FromChallenge(String& md5data, const String& challenge, const String& password); 02647 02654 static bool isMD5ChallengeCorrect(const String& md5data, const String& challenge, const String& password); 02655 02662 static void buildAddrSecret(String& buf, const String& secret, 02663 const SocketAddr& addr); 02664 02672 static int addrSecretAge(const String& buf, const String& secret, 02673 const SocketAddr& addr); 02674 02675 protected: 02681 bool processTrunkFrames(u_int32_t time = Time::msecNow()); 02682 02689 virtual void processEvent(IAXEvent* event); 02690 02697 IAXEvent* getEvent(u_int64_t time); 02698 02703 u_int16_t generateCallNo(); 02704 02709 void releaseCallNo(u_int16_t lcallno); 02710 02719 IAXTransaction* startLocalTransaction(IAXTransaction::Type type, const SocketAddr& addr, IAXIEList& ieList, bool trunking = false); 02720 02721 private: 02722 Socket m_socket; // Socket 02723 ObjList** m_transList; // Full transactions 02724 ObjList m_incompleteTransList; // Incomplete transactions (no remote call number) 02725 bool m_lUsedCallNo[IAX2_MAX_CALLNO + 1]; // Used local call numnmbers flags 02726 int m_lastGetEvIndex; // getEvent: keep last array entry 02727 // Parameters 02728 bool m_authRequired; // Automatically request authentication 02729 int m_maxFullFrameDataLen; // Max full frame data (IE list) length 02730 u_int16_t m_startLocalCallNo; // Start index of local call number allocation 02731 u_int16_t m_transListCount; // m_transList count 02732 u_int16_t m_retransCount; // Retransmission counter for each transaction belonging to this engine 02733 u_int16_t m_retransInterval; // Retransmission interval default value in miliseconds 02734 u_int16_t m_authTimeout; // Timeout (in seconds) of acknoledged auth frames sent 02735 u_int32_t m_transTimeout; // Timeout (in seconds) on remote request of transactions 02736 // belonging to this engine 02737 bool m_callToken; // Call token required on incoming calls 02738 String m_callTokenSecret; // Secret used to generate call tokens 02739 int m_callTokenAge; // Max allowed call token age 02740 bool m_showCallTokenFailures; // Print incoming call token failures to output 02741 bool m_rejectMissingCallToken; // Reject/ignore incoming calls without call token if mandatory 02742 bool m_printMsg; // Print frame to output 02743 // Media 02744 u_int32_t m_format; // The default media format 02745 u_int32_t m_formatVideo; // Default video format 02746 u_int32_t m_capability; // The media capability 02747 // Trunking 02748 Mutex m_mutexTrunk; // Mutex for trunk operations 02749 ObjList m_trunkList; // Trunk frames list 02750 u_int32_t m_trunkSendInterval; // Trunk frame send interval 02751 }; 02752 02753 } 02754 02755 #endif /* __YATEIAX_H */ 02756 02757 /* vi: set ts=8 sw=4 sts=4 noet: */