Yate
yateiax.h
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: */