00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef OPAL_IAX2_FRAME_H
00033 #define OPAL_IAX2_FRAME_H
00034
00035 #ifndef _PTLIB_H
00036 #include <ptlib.h>
00037 #endif
00038
00039 #include <opal/buildopts.h>
00040
00041 #if OPAL_IAX2
00042
00043 #include <iax2/ies.h>
00044 #include <iax2/remote.h>
00045
00046 #include <ptlib/sockets.h>
00047
00048 #ifdef P_USE_PRAGMA
00049 #pragma interface
00050 #endif
00051
00052 class IAX2Frame;
00053 class IAX2FrameList;
00054 class IAX2FullFrame;
00055 class IAX2FullFrameCng;
00056 class IAX2FullFrameDtmf;
00057 class IAX2FullFrameHtml;
00058 class IAX2FullFrameImage;
00059 class IAX2FullFrameNull;
00060 class IAX2FullFrameProtocol;
00061 class IAX2FullFrameSessionControl;
00062 class IAX2FullFrameText;
00063 class IAX2FullFrameVideo;
00064 class IAX2FullFrameVoice;
00065 class IAX2EndPoint;
00066 class IAX2Processor;
00067 class IAX2CallProcessor;
00068 class IAX2IeList;
00069 class IAX2MiniFrame;
00070 class IAX2Transmitter;
00071
00072
00073
00075 class IAX2Frame : public PObject
00076 {
00077 PCLASSINFO(IAX2Frame, PObject);
00078 public:
00080 IAX2Frame(IAX2EndPoint &_endpoint);
00081
00083 virtual ~IAX2Frame();
00084
00087 PBoolean ReadNetworkPacket(PUDPSocket &sock);
00088
00090 virtual PBoolean ProcessNetworkPacket();
00091
00093 virtual PBoolean IsFullFrame() { return isFullFrame; }
00094
00096 PBoolean IsVideo() const { return isVideo; }
00097
00099 PBoolean IsAudio() const { return isAudio; }
00100
00104 virtual BYTE *GetMediaDataPointer() { return data.GetPointer(); }
00105
00109 virtual PINDEX GetMediaDataSize() { return DataSize();}
00110
00112 PINDEX DataSize() { return data.GetSize(); }
00113
00115 IAX2Remote & GetRemoteInfo() { return remote; }
00116
00118 const BYTE * GetDataPointer() { return data + currentReadIndex; }
00119
00126 IAX2Frame * BuildAppropriateFrameType(IAX2Encryption &encryptionInfo);
00127
00129 IAX2Frame * BuildAppropriateFrameType();
00130
00132 PINDEX GetUnReadBytes() { return data.GetSize() - currentReadIndex; }
00133
00135 virtual PBoolean WriteHeader() { return false; }
00136
00139 virtual PBoolean TransmitPacket(PUDPSocket &sock);
00140
00142 virtual void PrintOn(ostream & strm) const;
00143
00145 static DWORD CalcTimeStamp(const PTimeInterval & callStartTick);
00146
00150 virtual void BuildTimeStamp(const PTimeInterval & callStartTick);
00151
00153 IAX2EndPoint & GetEndpoint() { return endpoint; }
00154
00157 PString IdString() const;
00158
00160 DWORD GetTimeStamp() { return timeStamp; }
00161
00163 void SetTimeStamp(DWORD newValue);
00164
00166 virtual PBoolean CallMustBeActive() { return true; }
00167
00169 enum IAX2FrameType {
00170 undefType = 0,
00171 dtmfType = 1,
00172 voiceType = 2,
00173 videoType = 3,
00174 controlType = 4,
00175 nullType = 5,
00176 iax2ProtocolType = 6,
00177 textType = 7,
00178 imageType = 8,
00179 htmlType = 9,
00180 cngType = 10,
00181 numFrameTypes = 11
00182 };
00183
00186 IAX2FrameType GetFrameType() { return frameType; }
00187
00191 virtual void InitialiseHeader(IAX2Processor * ) { }
00192
00195 PBoolean CanRetransmitFrame() const {return canRetransmitFrame; }
00196
00199 PString GetConnectionToken() const { return connectionToken; }
00200
00203 void SetConnectionToken(PString newToken) { connectionToken = newToken; }
00204
00207 void BuildConnectionToken();
00208
00211 PBoolean EncryptContents(IAX2Encryption &encData);
00212
00214 virtual PINDEX GetEncryptionOffset();
00215
00216 protected:
00217
00221 PBoolean DecryptContents(IAX2Encryption & encryption);
00222
00225 IAX2Remote remote;
00226
00229 IAX2FrameType frameType;
00230
00233 PBoolean Read1Byte(BYTE & res);
00234
00237 PBoolean Read2Bytes(PINDEX & res);
00238
00241 PBoolean Read2Bytes(WORD & res);
00242
00245 PBoolean Read4Bytes(DWORD & res);
00246
00249 void Write1Byte(BYTE newVal);
00250
00253 void Write1Byte(PINDEX newVal);
00254
00257 void Write2Bytes(PINDEX newVal);
00258
00261 void Write4Bytes(unsigned int newVal);
00262
00264 void ZeroAllValues();
00265
00267 IAX2EndPoint & endpoint;
00268
00271 PBYTEArray data;
00272
00274 PBoolean isFullFrame;
00275
00277 PBoolean isVideo;
00278
00280 PBoolean isAudio;
00281
00283 PINDEX currentReadIndex;
00284
00286 PINDEX currentWriteIndex;
00287
00289 DWORD timeStamp;
00290
00292 PBoolean canRetransmitFrame;
00293
00298 PString connectionToken;
00299
00302 DWORD presetTimeStamp;
00303 };
00304
00306
00307 class IAX2MiniFrame : public IAX2Frame
00308 {
00309 PCLASSINFO(IAX2MiniFrame, IAX2Frame);
00310 public:
00313 IAX2MiniFrame(const IAX2Frame & srcFrame);
00314
00316 IAX2MiniFrame(IAX2EndPoint & _endpoint);
00317
00326 IAX2MiniFrame(IAX2Processor * con, PBYTEArray &sound, PBoolean isAudio, DWORD usersTimeStamp = 0);
00327
00329 virtual ~IAX2MiniFrame();
00330
00333 virtual PBoolean ProcessNetworkPacket();
00334
00336 virtual PBoolean WriteHeader();
00337
00339 virtual void PrintOn(ostream & strm) const;
00340
00343 virtual BYTE *GetMediaDataPointer();
00344
00346 virtual PINDEX GetMediaDataSize();
00347
00349 void AlterTimeStamp(PINDEX newValue);
00350
00356 virtual void InitialiseHeader(IAX2Processor *processor);
00357
00359 virtual PINDEX GetEncryptionOffset();
00360
00361 protected:
00363 void ZeroAllValues();
00364 };
00365
00368
00369 class IAX2FullFrame : public IAX2Frame
00370 {
00371 PCLASSINFO(IAX2FullFrame, IAX2Frame);
00372 public:
00375 IAX2FullFrame(const IAX2Frame & srcFrame);
00376
00379 IAX2FullFrame(IAX2EndPoint &_endpoint);
00380
00383 virtual ~IAX2FullFrame();
00384
00386 PBoolean IsAckFrame() { return isAckFrame; }
00387
00389 PBoolean IsPingFrame();
00390
00392 PBoolean IsNewFrame();
00393
00395 PBoolean IsLagRqFrame();
00396
00398 PBoolean IsLagRpFrame();
00399
00401 PBoolean IsPongFrame();
00402
00404 PBoolean IsAuthReqFrame();
00405
00407 PBoolean IsVnakFrame();
00408
00410 PBoolean IsRegReqFrame();
00411
00413 PBoolean IsRegAuthFrame();
00414
00416 PBoolean IsRegAckFrame();
00417
00419 PBoolean IsRegRelFrame();
00420
00422 PBoolean IsRegRejFrame();
00423
00425 PBoolean IsCallTokenFrame();
00426
00429 PBoolean FrameIncrementsInSeqNo();
00430
00433 virtual PBoolean IsFullFrame() { return true; }
00434
00438 PBoolean IsHangupFrame();
00439
00441 void ZeroAllValues();
00442
00445 virtual PBoolean ProcessNetworkPacket();
00446
00449 virtual PBoolean TransmitPacket(PUDPSocket &sock);
00450
00452 PString GetFullFrameName() const;
00453
00455 virtual PString GetSubClassName() const
00456 { return PString(" subclass=") + PString(subClass); }
00457
00461 void MarkDeleteNow();
00462
00467 void MarkVnakSendNow();
00468
00471 virtual BYTE *GetMediaDataPointer();
00472
00474 virtual PINDEX GetMediaDataSize();
00475
00477 PINDEX GetSubClass() const { return subClass; }
00478
00480 void SetSubClass(PINDEX newValue) { subClass = newValue;}
00481
00485 virtual PBoolean WriteHeader();
00486
00489 void ModifyFrameHeaderSequenceNumbers(PINDEX inNo, PINDEX outNo);
00490
00495 void ModifyFrameTimeStamp(PINDEX newTimeStamp);
00496
00498 virtual PBoolean InformationElementsPresent() { return false; }
00499
00502 PBoolean SendFrameNow() { return sendFrameNow; }
00503
00506 PBoolean DeleteFrameNow() { return deleteFrameNow; }
00507
00509 IAX2SequenceNumbers & GetSequenceInfo() { return sequence; }
00510
00512 virtual void PrintOn(ostream & strm) const;
00513
00515 void MarkAsResent();
00516
00519 PBoolean operator *= (IAX2FullFrame & other);
00520
00523 enum ConnectionRequired {
00524 callActive,
00525 callIrrelevant
00526 };
00527
00529 virtual BYTE GetFullFrameType() { return 0; }
00530
00532 virtual PINDEX GetEncryptionOffset() { return 4; }
00533
00534 protected:
00536 virtual PBoolean CallMustBeActive() { return callMustBeActive; }
00537
00539 void UnCompressSubClass(BYTE a);
00540
00542 int CompressSubClass();
00543
00545 void ClearListFlags();
00546
00552 virtual void InitialiseHeader(IAX2Processor *processor);
00553
00554 #ifdef DOC_PLUS_PLUS
00555
00558 void OnTransmissionTimeout(PTimer &, INT);
00559 #else
00560 PDECLARE_NOTIFIER(PTimer, IAX2FullFrame, OnTransmissionTimeout);
00561 #endif
00562
00563 PTimer transmissionTimer;
00564
00566 PINDEX subClass;
00567
00569 PTimeInterval retryDelta;
00570
00572 PTimeInterval timeOffset;
00573
00575 PINDEX retries;
00576
00578 enum RetryTime {
00579 minRetryTime = 1000,
00580 maxRetryTime = 010000,
00581 maxRetries = 3
00582 };
00583
00585 IAX2SequenceNumbers sequence;
00586
00588 PBoolean sendFrameNow;
00589
00591 PBoolean deleteFrameNow;
00592
00594 PBoolean packetResent;
00595
00597 PBoolean callMustBeActive;
00598
00600 PBoolean isAckFrame;
00601 };
00602
00604
00609 class IAX2FullFrameDtmf : public IAX2FullFrame
00610 {
00611 PCLASSINFO(IAX2FullFrameDtmf, IAX2FullFrame);
00612 public:
00615 IAX2FullFrameDtmf(const IAX2Frame & srcFrame);
00616
00619 IAX2FullFrameDtmf(const IAX2FullFrame & srcFrame);
00620
00623 IAX2FullFrameDtmf(IAX2Processor *processor,
00624 char subClassValue
00625 );
00626
00629 IAX2FullFrameDtmf(IAX2Processor *processor,
00630 PString subClassValue
00631 );
00632
00633
00635 virtual PString GetSubClassName() const;
00636
00638 enum DtmfSc {
00639 dtmf0 = 48,
00640 dtmf1 = 49,
00641 dtmf2 = 50,
00642 dtmf3 = 51,
00643 dtmf4 = 52,
00644 dtmf5 = 53,
00645 dtmf6 = 54,
00646 dtmf7 = 55,
00647 dtmf8 = 56,
00648 dtmf9 = 57,
00649 dtmfA = 65,
00650 dtmfB = 66,
00651 dtmfC = 67,
00652 dtmfD = 68,
00653 dtmfStar = 42,
00654 dtmfHash = 35
00655 };
00656
00658 virtual BYTE GetFullFrameType() { return dtmfType; }
00659
00660 protected:
00661 };
00662
00664
00671 class IAX2FullFrameVoice : public IAX2FullFrame
00672 {
00673 PCLASSINFO(IAX2FullFrameVoice, IAX2FullFrame);
00674 public:
00675
00678 IAX2FullFrameVoice(const IAX2Frame & srcFrame);
00679
00682 IAX2FullFrameVoice(const IAX2FullFrame & srcFrame);
00683
00692 IAX2FullFrameVoice(IAX2CallProcessor *processor, PBYTEArray &sound,
00693 PINDEX usersTimeStamp = 0);
00694
00696 virtual ~IAX2FullFrameVoice();
00697
00699 virtual PString GetSubClassName() const;
00700
00703 static PString GetSubClassName(unsigned short testValue)
00704 { return GetSubClassName((unsigned int) testValue); }
00705
00708 static PString GetSubClassName(unsigned int testValue);
00709
00713 static PString GetOpalNameOfCodec(PINDEX testValue);
00714
00716 static PString GetSubClassName(int testValue)
00717 { return GetSubClassName((unsigned short) testValue); }
00718
00721 static unsigned short OpalNameToIax2Value(const PString opalName);
00722
00724 enum AudioSc {
00725 g7231 = 1,
00726 gsm = 2,
00727 g711ulaw = 4,
00728 g711alaw = 8,
00729 mp3 = 0x10,
00730 adpcm = 0x20,
00731 pcm = 0x40,
00732 lpc10 = 0x80,
00733 g729 = 0x100,
00734 speex = 0x200,
00735 ilbc = 0x400,
00736 supportedCodecs = 11
00737 };
00738
00740 virtual BYTE GetFullFrameType() { return voiceType; }
00741 };
00743
00748 class IAX2FullFrameVideo : public IAX2FullFrame
00749 {
00750 PCLASSINFO(IAX2FullFrameVideo, IAX2FullFrame);
00751 public:
00752
00755 IAX2FullFrameVideo(const IAX2Frame & srcFrame);
00756
00759 IAX2FullFrameVideo(const IAX2FullFrame & srcFrame);
00760
00762 virtual PString GetSubClassName() const;
00763
00765 enum VideoSc {
00766 jpeg = 0x10000,
00767 png = 0x20000,
00768 h261 = 0x40000,
00769 h263 = 0x80000
00770 };
00771
00773 virtual BYTE GetFullFrameType() { return videoType; }
00774 protected:
00775 };
00776
00778
00783 class IAX2FullFrameSessionControl : public IAX2FullFrame
00784 {
00785 PCLASSINFO(IAX2FullFrameSessionControl, IAX2FullFrame);
00786 public:
00787
00789 enum SessionSc {
00790 hangup = 1,
00791 ring = 2,
00792 ringing = 3,
00793 answer = 4,
00794 busy = 5,
00795 tkoffhk = 6,
00796 offhook = 7,
00797 congestion = 8,
00798 flashhook = 9,
00799 wink = 10,
00800 option = 11,
00801 keyRadio = 12,
00802 unkeyRadio = 13,
00803 callProgress = 14,
00804 callProceeding = 15,
00805 callOnHold = 16,
00806 callHoldRelease = 17,
00807 stopSounds = 255
00808 };
00809
00810
00811
00814 IAX2FullFrameSessionControl(const IAX2Frame & srcFrame);
00815
00818 IAX2FullFrameSessionControl(const IAX2FullFrame & srcFrame);
00819
00822 IAX2FullFrameSessionControl(IAX2Processor *processor,
00823 PINDEX subClassValue
00824 );
00825
00828 IAX2FullFrameSessionControl(IAX2Processor *processor,
00829 SessionSc subClassValue
00830 );
00831
00833 virtual ~IAX2FullFrameSessionControl() { }
00834
00836 virtual PString GetSubClassName() const;
00837
00839 virtual BYTE GetFullFrameType() { return controlType; }
00840
00841 protected:
00842 };
00843
00845
00851 class IAX2FullFrameNull : public IAX2FullFrame
00852 {
00853 PCLASSINFO(IAX2FullFrameNull, IAX2FullFrame);
00854 public:
00857 IAX2FullFrameNull(IAX2EndPoint & endpoint) : IAX2FullFrame(endpoint) { }
00858
00862 IAX2FullFrameNull(const IAX2Frame & srcFrame);
00863
00867 IAX2FullFrameNull(const IAX2FullFrame & srcFrame);
00868
00870 virtual PString GetSubClassName() const { return PString(""); }
00871
00873 virtual BYTE GetFullFrameType() { return nullType; }
00874
00875 protected:
00876 };
00877
00879
00885 class IAX2FullFrameProtocol : public IAX2FullFrame
00886 {
00887 PCLASSINFO(IAX2FullFrameProtocol, IAX2FullFrame);
00888 public:
00889
00891 enum ProtocolSc {
00892 cmdNew = 1,
00893 cmdPing = 2,
00894 cmdPong = 3,
00895 cmdAck = 4,
00896 cmdHangup = 5,
00897 cmdReject = 6,
00898 cmdAccept = 7,
00899 cmdAuthReq = 8,
00900 cmdAuthRep = 9,
00901 cmdInval = 10,
00902 cmdLagRq = 11,
00903 cmdLagRp = 12,
00904 cmdRegReq = 13,
00905 cmdRegAuth = 14,
00906 cmdRegAck = 15,
00907 cmdRegRej = 16,
00908 cmdRegRel = 17,
00909 cmdVnak = 18,
00910 cmdDpReq = 19,
00911 cmdDpRep = 20,
00912 cmdDial = 21,
00913 cmdTxreq = 22,
00914 cmdTxcnt = 23,
00915 cmdTxacc = 24,
00916 cmdTxready = 25,
00917 cmdTxrel = 26,
00918 cmdTxrej = 27,
00919 cmdQuelch = 28,
00920 cmdUnquelch = 29,
00921 cmdPoke = 30,
00922 cmdPage = 31,
00923 cmdMwi = 32,
00924 cmdUnsupport = 33,
00925 cmdTransfer = 34,
00926 cmdProvision = 35,
00927 cmdFwDownl = 36,
00928 cmdFwData = 37,
00929 cmdTxMedia = 38,
00930 cmdRtKey = 39,
00931 cmdCallToken = 40
00932 };
00933
00937 IAX2FullFrameProtocol(const IAX2Frame & srcFrame);
00938
00942 IAX2FullFrameProtocol(const IAX2FullFrame & srcFrame);
00943
00946 IAX2FullFrameProtocol(IAX2Processor *processor,
00947 PINDEX subClassValue,
00948 ConnectionRequired needCon = IAX2FullFrame::callActive
00950 );
00951
00954 IAX2FullFrameProtocol(IAX2Processor *processor,
00955 ProtocolSc subClassValue,
00956 ConnectionRequired needCon=IAX2FullFrame::callActive
00958 );
00959
00965 IAX2FullFrameProtocol(IAX2Processor *processor,
00966 ProtocolSc subClassValue,
00967 IAX2FullFrame *inReplyTo,
00968 ConnectionRequired needCon = IAX2FullFrame::callActive
00970 );
00971
00973 virtual ~IAX2FullFrameProtocol();
00974
00976 void SetRetransmissionRequired();
00977
00979 virtual PBoolean InformationElementsPresent() { return !ieElements.IsEmpty(); }
00980
00982 ProtocolSc GetSubClass() const { return (ProtocolSc) subClass; }
00983
00985 virtual PString GetSubClassName() const;
00986
00988 static PString GetSubClassName(PINDEX t);
00989
00992 IAX2Ie *GetIeAt(PINDEX i) { return ieElements.GetIeAt(i); }
00993
00995 void AppendIe(IAX2Ie *newElement) { ieElements.AppendIe(newElement); }
00996
00999 void WriteIeAsBinaryData();
01000
01004 void CopyDataFromIeListTo(IAX2IeData &res);
01005
01008 void GetRemoteCapability(unsigned int & capability,
01009 unsigned int & preferred);
01010
01013 virtual BYTE GetFullFrameType() { return iax2ProtocolType; }
01014
01016 virtual void PrintOn(ostream & strm) const;
01017
01020 PBoolean GetCallTokenIe(IAX2IeCallToken & callToken);
01021
01022 protected:
01023
01026 PBoolean ReadInformationElements();
01027
01028
01031 IAX2IeList ieElements;
01032
01034 #if PTRACING
01035 friend ostream & operator<<(ostream & o, ProtocolSc t);
01036 #endif
01037 };
01038
01040
01045 class IAX2FullFrameText : public IAX2FullFrame
01046 {
01047 PCLASSINFO(IAX2FullFrameText, IAX2FullFrame);
01048 public:
01049
01052 IAX2FullFrameText(IAX2Processor *processor,
01053 const PString& textValue
01054 );
01055
01058 IAX2FullFrameText(const IAX2Frame & srcFrame);
01059
01062 IAX2FullFrameText(const IAX2FullFrame & srcFrame);
01063
01065 virtual PString GetSubClassName() const;
01066
01068 virtual BYTE GetFullFrameType() { return textType; }
01069
01071 PString GetTextString() const;
01072
01073 protected:
01074
01076 PString internalText;
01077 };
01079
01084 class IAX2FullFrameImage : public IAX2FullFrame
01085 {
01086 PCLASSINFO(IAX2FullFrameImage, IAX2FullFrame);
01087 public:
01088
01091 IAX2FullFrameImage(const IAX2Frame & srcFrame);
01092
01095 IAX2FullFrameImage(const IAX2FullFrame & srcFrame);
01096
01098 virtual PString GetSubClassName() const;
01099
01101 virtual BYTE GetFullFrameType() { return imageType; }
01102 protected:
01103 };
01104
01106
01111 class IAX2FullFrameHtml : public IAX2FullFrame
01112 {
01113 PCLASSINFO(IAX2FullFrameHtml, IAX2FullFrame);
01114 public:
01115
01118 IAX2FullFrameHtml(const IAX2Frame & srcFrame);
01119
01122 IAX2FullFrameHtml(const IAX2FullFrame & srcFrame);
01123
01125 virtual PString GetSubClassName() const;
01126
01128 virtual BYTE GetFullFrameType() { return htmlType; }
01129 protected:
01130 };
01131
01133
01137 class IAX2FullFrameCng : public IAX2FullFrame
01138 {
01139 PCLASSINFO(IAX2FullFrameCng, IAX2FullFrame);
01140 public:
01141
01144 IAX2FullFrameCng(const IAX2Frame & srcFrame);
01145
01148 IAX2FullFrameCng(const IAX2FullFrame & srcFrame);
01149
01151 virtual PString GetSubClassName() const;
01152
01154 virtual BYTE GetFullFrameType() { return cngType; }
01155 protected:
01156 };
01157
01159
01160 PDECLARE_LIST (IAX2FrameList, IAX2Frame *)
01161 #ifdef DOC_PLUS_PLUS //This makes emacs bracket matching code happy.
01162
01168 class IAX2FrameList : public IAX2Frame *
01169 {
01170 #endif
01171 public:
01172 ~IAX2FrameList();
01173
01175 void ReportList(PString & answer);
01176
01178 IAX2Frame *GetLastFrame();
01179
01181 void Initialise();
01182
01184 PBoolean Empty() { return GetSize() == 0; }
01185
01187 void GrabContents(IAX2FrameList &src);
01188
01191 void DeleteMatchingSendFrame(IAX2FullFrame *reply);
01192
01196 void SendVnakRequestedFrames(IAX2FullFrameProtocol &src);
01197
01199 void AddNewFrame(IAX2Frame *src);
01200
01202 void GetResendFramesDeleteOldFrames(IAX2FrameList & framesToSend);
01203
01205 virtual PINDEX GetSize() { PWaitAndSignal m(mutex); return PAbstractList::GetSize(); }
01206
01208 void MarkAllAsResent();
01209
01210 protected:
01212 virtual PINDEX GetEntries() { return PAbstractList::GetSize(); }
01213
01215 PMutex mutex;
01216 };
01217
01219
01223 class IAX2ActiveFrameList : public IAX2FrameList
01224 {
01225 PCLASSINFO(IAX2ActiveFrameList, IAX2FrameList);
01226 public:
01227 IAX2ActiveFrameList() { Initialise(); }
01228 };
01230
01231
01232 #endif // OPAL_IAX2
01233
01234 #endif // OPAL_IAX2_FRAME_H
01235
01236
01237
01238
01239
01240
01241
01242
01243