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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 #ifndef __OPAL_SIPPDU_H
00171 #define __OPAL_SIPPDU_H
00172
00173 #ifdef P_USE_PRAGMA
00174 #pragma interface
00175 #endif
00176
00177
00178 #include <ptclib/mime.h>
00179 #include <ptclib/url.h>
00180 #include <sip/sdp.h>
00181
00182
00183 class OpalTransport;
00184 class OpalTransportAddress;
00185
00186 class SIPEndPoint;
00187 class SIPConnection;
00188 class SIP_PDU;
00189
00190
00192
00193
00199 class SIPURL : public PURL
00200 {
00201 PCLASSINFO(SIPURL, PURL);
00202 public:
00203 SIPURL();
00204
00207 SIPURL(
00208 const char * cstr,
00209 const char * defaultScheme = NULL
00210 );
00211
00214 SIPURL(
00215 const PString & str,
00216 const char * defaultScheme = NULL
00217 );
00218
00226 SIPURL(
00227 const PString & name,
00228 const OpalTransportAddress & address,
00229 WORD listenerPort = 0
00230 );
00231
00235 PString AsQuotedString() const;
00236
00239 PString GetDisplayName() const;
00240
00241 void SetDisplayName(const PString & str)
00242 { displayName = str; }
00243
00244 OpalTransportAddress GetHostAddress() const;
00245
00249 void AdjustForRequestURI();
00250
00251 protected:
00270 virtual BOOL InternalParse(
00271 const char * cstr,
00272 const char * defaultScheme
00273 );
00274
00275 PString displayName;
00276 };
00277
00278
00280
00281
00312 class SIPMIMEInfo : public PMIMEInfo
00313 {
00314 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00315 public:
00316 SIPMIMEInfo(BOOL compactForm = FALSE);
00317
00318 void SetForm(BOOL v) { compactForm = v; }
00319
00320 PString GetContentType() const;
00321 void SetContentType(const PString & v);
00322
00323 PString GetContentEncoding() const;
00324 void SetContentEncoding(const PString & v);
00325
00326 PString GetFrom() const;
00327 void SetFrom(const PString & v);
00328
00329 PString GetAccept() const;
00330 void SetAccept(const PString & v);
00331
00332 PString GetAcceptEncoding() const;
00333 void SetAcceptEncoding(const PString & v);
00334
00335 PString GetAcceptLanguage() const;
00336 void SetAcceptLanguage(const PString & v);
00337
00338 PString GetAllow() const;
00339 void SetAllow(const PString & v);
00340
00341 PString GetCallID() const;
00342 void SetCallID(const PString & v);
00343
00344 PString GetContact() const;
00345 void SetContact(const PString & v);
00346 void SetContact(const SIPURL & url);
00347
00348 PString GetSubject() const;
00349 void SetSubject(const PString & v);
00350
00351 PString GetTo() const;
00352 void SetTo(const PString & v);
00353
00354 PString GetVia() const;
00355 void SetVia(const PString & v);
00356
00357 PStringList GetViaList() const;
00358 void SetViaList(const PStringList & v);
00359
00360 PString GetReferTo() const;
00361 void SetReferTo(const PString & r);
00362
00363 PString GetReferredBy() const;
00364 void SetReferredBy(const PString & r);
00365
00366 PINDEX GetContentLength() const;
00367 void SetContentLength(PINDEX v);
00368 BOOL IsContentLengthPresent() const;
00369
00370 PString GetCSeq() const;
00371 void SetCSeq(const PString & v);
00372
00373 PString GetDate() const;
00374 void SetDate(const PString & v);
00375 void SetDate(const PTime & t);
00376 void SetDate(void);
00377
00378 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00379 void SetExpires(unsigned v);
00380
00381 PINDEX GetMaxForwards() const;
00382 void SetMaxForwards(PINDEX v);
00383
00384 PINDEX GetMinExpires() const;
00385 void SetMinExpires(PINDEX v);
00386
00387 PString GetProxyAuthenticate() const;
00388 void SetProxyAuthenticate(const PString & v);
00389
00390 PStringList GetRoute() const;
00391 void SetRoute(const PStringList & v);
00392
00393 PStringList GetRecordRoute() const;
00394 void SetRecordRoute(const PStringList & v);
00395
00396 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00397
00398 PString GetSupported() const;
00399 void SetSupported(const PString & v);
00400
00401 PString GetUnsupported() const;
00402 void SetUnsupported(const PString & v);
00403
00404 PString GetEvent() const;
00405 void SetEvent(const PString & v);
00406
00407 PString GetSubscriptionState() const;
00408 void SetSubscriptionState(const PString & v);
00409
00410 PString GetUserAgent() const;
00411 void SetUserAgent(const SIPEndPoint & sipep);
00412
00413 PString GetWWWAuthenticate() const;
00414 void SetWWWAuthenticate(const PString & v);
00415
00416
00419 PString GetFieldParameter(const PString &,
00420 const PString &);
00421
00426 void SetFieldParameter(const PString &,
00427 PString &,
00428 const PString &);
00429
00432 BOOL HasFieldParameter(const PString &,
00433 const PString &);
00434
00435 protected:
00438 PStringList GetRouteList(const char * name) const;
00439
00443 void SetRouteList(const char * name, const PStringList & v);
00444
00447 PString GetFullOrCompact(const char * fullForm, char compactForm) const;
00448
00450 BOOL compactForm;
00451 };
00452
00453
00455
00456
00457 class SIPAuthentication : public PObject
00458 {
00459 PCLASSINFO(SIPAuthentication, PObject);
00460 public:
00461 SIPAuthentication(
00462 const PString & username = PString::Empty(),
00463 const PString & password = PString::Empty()
00464 );
00465
00466 #if PWLIB_MAJOR >= 1 && PWLIB_MINOR >= 11
00467 SIPAuthentication & operator =(const SIPAuthentication & auth)
00468 {
00469 isProxy = auth.isProxy;
00470 authRealm = auth.authRealm;
00471 username = auth.username;
00472 password = auth.password;
00473 nonce = auth.nonce;
00474 algorithm = auth.algorithm;
00475 opaque = auth.opaque;
00476
00477 qopAuth = auth.qopAuth;
00478 qopAuthInt = auth.qopAuthInt;
00479 cnonce = auth.cnonce;
00480 nonceCount.SetValue(auth.nonceCount);
00481
00482 return *this;
00483 }
00484 #endif
00485
00486 BOOL Parse(
00487 const PCaselessString & auth,
00488 BOOL proxy
00489 );
00490
00491 BOOL IsValid() const;
00492
00493 BOOL Authorise(
00494 SIP_PDU & pdu
00495 ) const;
00496
00497 enum Algorithm {
00498 Algorithm_MD5,
00499 NumAlgorithms
00500 };
00501
00502 BOOL IsProxy() const { return isProxy; }
00503 const PString & GetAuthRealm() const { return authRealm; }
00504 const PString & GetUsername() const { return username; }
00505 const PString & GetPassword() const { return password; }
00506 const PString & GetNonce() const { return nonce; }
00507 Algorithm GetAlgorithm() const { return algorithm; }
00508 const PString & GetOpaque() const { return opaque; }
00509
00510 void SetUsername(const PString & user) { username = user; }
00511 void SetPassword(const PString & pass) { password = pass; }
00512 void SetAuthRealm(const PString & r) { authRealm = r; }
00513
00514 protected:
00515 BOOL isProxy;
00516 PString authRealm;
00517 PString username;
00518 PString password;
00519 PString nonce;
00520 Algorithm algorithm;
00521 PString opaque;
00522
00523 BOOL qopAuth;
00524 BOOL qopAuthInt;
00525 PString cnonce;
00526 mutable PAtomicInteger nonceCount;
00527 };
00528
00529
00531
00532
00538 class SIP_PDU : public PObject
00539 {
00540 PCLASSINFO(SIP_PDU, PObject);
00541 public:
00542 enum Methods {
00543 Method_INVITE,
00544 Method_ACK,
00545 Method_OPTIONS,
00546 Method_BYE,
00547 Method_CANCEL,
00548 Method_REGISTER,
00549 Method_SUBSCRIBE,
00550 Method_NOTIFY,
00551 Method_REFER,
00552 Method_MESSAGE,
00553 NumMethods
00554 };
00555
00556 enum StatusCodes {
00557 IllegalStatusCode,
00558
00559 Information_Trying = 100,
00560 Information_Ringing = 180,
00561 Information_CallForwarded = 181,
00562 Information_Queued = 182,
00563 Information_Session_Progress = 183,
00564
00565 Successful_OK = 200,
00566 Successful_Accepted = 202,
00567
00568 Redirection_MultipleChoices = 300,
00569 Redirection_MovedPermanently = 301,
00570 Redirection_MovedTemporarily = 302,
00571 Redirection_UseProxy = 305,
00572 Redirection_AlternativeService = 380,
00573
00574 Failure_BadRequest = 400,
00575 Failure_UnAuthorised = 401,
00576 Failure_PaymentRequired = 402,
00577 Failure_Forbidden = 403,
00578 Failure_NotFound = 404,
00579 Failure_MethodNotAllowed = 405,
00580 Failure_NotAcceptable = 406,
00581 Failure_ProxyAuthenticationRequired = 407,
00582 Failure_RequestTimeout = 408,
00583 Failure_Conflict = 409,
00584 Failure_Gone = 410,
00585 Failure_LengthRequired = 411,
00586 Failure_RequestEntityTooLarge = 413,
00587 Failure_RequestURITooLong = 414,
00588 Failure_UnsupportedMediaType = 415,
00589 Failure_UnsupportedURIScheme = 416,
00590 Failure_BadExtension = 420,
00591 Failure_ExtensionRequired = 421,
00592 Failure_IntervalTooBrief = 423,
00593 Failure_TemporarilyUnavailable = 480,
00594 Failure_TransactionDoesNotExist = 481,
00595 Failure_LoopDetected = 482,
00596 Failure_TooManyHops = 483,
00597 Failure_AddressIncomplete = 484,
00598 Failure_Ambiguous = 485,
00599 Failure_BusyHere = 486,
00600 Failure_RequestTerminated = 487,
00601 Failure_NotAcceptableHere = 488,
00602 Failure_BadEvent = 489,
00603 Failure_RequestPending = 491,
00604 Failure_Undecipherable = 493,
00605
00606 Failure_InternalServerError = 500,
00607 Failure_NotImplemented = 501,
00608 Failure_BadGateway = 502,
00609 Failure_ServiceUnavailable = 503,
00610 Failure_ServerTimeout = 504,
00611 Failure_SIPVersionNotSupported = 505,
00612 Failure_MessageTooLarge = 513,
00613
00614 GlobalFailure_BusyEverywhere = 600,
00615 GlobalFailure_Decline = 603,
00616 GlobalFailure_DoesNotExistAnywhere = 604,
00617 GlobalFailure_NotAcceptable = 606,
00618
00619 MaxStatusCode = 699
00620 };
00621
00622 static const char * GetStatusCodeDescription (int code);
00623
00624 enum {
00625 MaxSize = 65535
00626 };
00627
00628 SIP_PDU();
00629
00632 SIP_PDU(
00633 Methods method,
00634 const SIPURL & dest,
00635 const PString & to,
00636 const PString & from,
00637 const PString & callID,
00638 unsigned cseq,
00639 const OpalTransportAddress & via
00640 );
00643 SIP_PDU(
00644 Methods method,
00645 SIPConnection & connection,
00646 const OpalTransport & transport
00647 );
00648
00652 SIP_PDU(
00653 const SIP_PDU & request,
00654 StatusCodes code,
00655 const char * contact = NULL,
00656 const char * extra = NULL
00657 );
00658 SIP_PDU(const SIP_PDU &);
00659 SIP_PDU & operator=(const SIP_PDU &);
00660 ~SIP_PDU();
00661
00662 void PrintOn(
00663 ostream & strm
00664 ) const;
00665
00666 void Construct(
00667 Methods method
00668 );
00669 void Construct(
00670 Methods method,
00671 const SIPURL & dest,
00672 const PString & to,
00673 const PString & from,
00674 const PString & callID,
00675 unsigned cseq,
00676 const OpalTransportAddress & via
00677 );
00678 void Construct(
00679 Methods method,
00680 SIPConnection & connection,
00681 const OpalTransport & transport
00682 );
00683
00688 BOOL SetRoute(SIPConnection & connection);
00689
00692 void SetAllow(void);
00693
00696 void AdjustVia(OpalTransport & transport);
00697
00701 OpalTransportAddress GetViaAddress(OpalEndPoint &);
00702
00706 OpalTransportAddress GetSendAddress(SIPConnection &);
00707
00710 BOOL Read(
00711 OpalTransport & transport
00712 );
00713
00716 BOOL Write(
00717 OpalTransport & transport
00718 );
00719
00720 PString GetTransactionID() const;
00721
00722 Methods GetMethod() const { return method; }
00723 StatusCodes GetStatusCode () const { return statusCode; }
00724 const SIPURL & GetURI() const { return uri; }
00725 unsigned GetVersionMajor() const { return versionMajor; }
00726 unsigned GetVersionMinor() const { return versionMinor; }
00727 const PString & GetEntityBody() const { return entityBody; }
00728 PString & GetEntityBody() { return entityBody; }
00729 const PString & GetInfo() const { return info; }
00730 const SIPMIMEInfo & GetMIME() const { return mime; }
00731 SIPMIMEInfo & GetMIME() { return mime; }
00732 BOOL HasSDP() const { return sdp != NULL; }
00733 SDPSessionDescription & GetSDP() const { return *PAssertNULL(sdp); }
00734 void SetSDP(SDPSessionDescription * s) { sdp = s; }
00735 void SetSDP(const SDPSessionDescription & s) { sdp = new SDPSessionDescription(s); }
00736
00737 protected:
00738
00739 Methods method;
00740 StatusCodes statusCode;
00741 SIPURL uri;
00742 unsigned versionMajor;
00743 unsigned versionMinor;
00744 PString info;
00745 SIPMIMEInfo mime;
00746 PString entityBody;
00747
00748 SDPSessionDescription * sdp;
00749 };
00750
00751
00752 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00753
00754
00756
00757
00768 class SIPTransaction : public SIP_PDU
00769 {
00770 PCLASSINFO(SIPTransaction, SIP_PDU);
00771 public:
00772 SIPTransaction(
00773 SIPEndPoint & endpoint,
00774 OpalTransport & transport,
00775 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00776 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00777 );
00781 SIPTransaction(
00782 SIPConnection & connection,
00783 OpalTransport & transport,
00784 Methods method = NumMethods
00785 );
00786 ~SIPTransaction();
00787
00788 BOOL Start();
00789 BOOL IsInProgress() const { return state == Trying && state == Proceeding; }
00790 BOOL IsFailed() const { return state > Terminated_Success; }
00791 BOOL IsFinished() { return finished.Wait(0); }
00792 BOOL IsCanceled() const {return state == Terminated_Cancelled;}
00793 void Wait();
00794 BOOL SendCANCEL();
00795
00796 virtual BOOL OnReceivedResponse(SIP_PDU & response);
00797 virtual BOOL OnCompleted(SIP_PDU & response);
00798
00799 OpalTransport & GetTransport() const { return transport; }
00800 SIPConnection * GetConnection() const { return connection; }
00801
00802 const OpalTransportAddress & GetLocalAddress() const { return localAddress; }
00803
00804 protected:
00805 void Construct(
00806 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00807 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00808 );
00809 BOOL ResendCANCEL();
00810
00811 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00812 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00813
00814 enum States {
00815 NotStarted,
00816 Trying,
00817 Proceeding,
00818 Cancelling,
00819 Completed,
00820 Terminated_Success,
00821 Terminated_Timeout,
00822 Terminated_RetriesExceeded,
00823 Terminated_TransportError,
00824 Terminated_Cancelled,
00825 NumStates
00826 };
00827 virtual void SetTerminated(States newState);
00828
00829 SIPEndPoint & endpoint;
00830 OpalTransport & transport;
00831 SIPConnection * connection;
00832
00833 States state;
00834 unsigned retry;
00835 PTimer retryTimer;
00836 PTimer completionTimer;
00837
00838 PSyncPoint finished;
00839 PTimedMutex mutex;
00840
00841 PTimeInterval retryTimeoutMin;
00842 PTimeInterval retryTimeoutMax;
00843
00844 OpalTransportAddress localAddress;
00845 };
00846
00847
00848 PLIST(SIPTransactionList, SIPTransaction);
00849 PDICTIONARY(SIPTransactionDict, PString, SIPTransaction);
00850
00851
00853
00854
00860 class SIPInvite : public SIPTransaction
00861 {
00862 PCLASSINFO(SIPInvite, SIPTransaction);
00863 public:
00864 SIPInvite(
00865 SIPConnection & connection,
00866 OpalTransport & transport
00867 );
00868 SIPInvite(
00869 SIPConnection & connection,
00870 OpalTransport & transport,
00871 RTP_SessionManager & sm
00872 );
00873 SIPInvite(
00874 SIPConnection & connection,
00875 OpalTransport & transport,
00876 unsigned rtpSessionId
00877 );
00878
00879 virtual BOOL OnReceivedResponse(SIP_PDU & response);
00880
00881 RTP_SessionManager & GetSessionManager() { return rtpSessions; }
00882
00883 protected:
00884 RTP_SessionManager rtpSessions;
00885 };
00886
00887
00889
00890 class SIPRegister : public SIPTransaction
00891 {
00892 PCLASSINFO(SIPRegister, SIPTransaction);
00893 public:
00894 SIPRegister(
00895 SIPEndPoint & endpoint,
00896 OpalTransport & transport,
00897 const SIPURL & address,
00898 const PString & id,
00899 unsigned expires,
00900 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00901 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00902 );
00903 };
00904
00905
00907
00908 class SIPMWISubscribe : public SIPTransaction
00909 {
00910 PCLASSINFO(SIPMWISubscribe, SIPTransaction);
00911 public:
00914 enum MWIType {
00915
00916 VoiceMessage,
00917 FaxMessage,
00918 PagerMessage,
00919 MultimediaMessage,
00920 TextMessage,
00921 None
00922 };
00923
00924 SIPMWISubscribe(
00925 SIPEndPoint & endpoint,
00926 OpalTransport & transport,
00927 const SIPURL & address,
00928 const PString & id,
00929 unsigned expires
00930 );
00931 };
00932
00933
00935
00936 class SIPRefer : public SIPTransaction
00937 {
00938 PCLASSINFO(SIPRefer, SIPTransaction);
00939 public:
00940 SIPRefer(
00941 SIPConnection & connection,
00942 OpalTransport & transport,
00943 const PString & refer
00944 );
00945 SIPRefer(
00946 SIPConnection & connection,
00947 OpalTransport & transport,
00948 const PString & refer,
00949 const PString & referred_by
00950 );
00951 protected:
00952 void Construct(
00953 SIPConnection & connection,
00954 OpalTransport & transport,
00955 const PString & refer,
00956 const PString & referred_by = PString::Empty()
00957 );
00958 };
00959
00960
00962
00963
00964
00965
00966 class SIPReferNotify : public SIPTransaction
00967 {
00968 PCLASSINFO(SIPReferNotify, SIPTransaction);
00969 public:
00970 SIPReferNotify(
00971 SIPConnection & connection,
00972 OpalTransport & transport,
00973 StatusCodes code
00974 );
00975 };
00976
00977
00979
00980
00981
00982 class SIPMessage : public SIPTransaction
00983 {
00984 PCLASSINFO(SIPMessage, SIPTransaction);
00985
00986 public:
00987 SIPMessage(
00988 SIPEndPoint & ep,
00989 OpalTransport & trans,
00990 const SIPURL & address,
00991 const PString & body
00992 );
00993 };
00994
00995
00997
00998
00999
01000
01001 class SIPAck : public SIP_PDU
01002 {
01003 PCLASSINFO(SIPAck, SIP_PDU);
01004 public:
01005
01006 SIPAck(
01007 SIPEndPoint & ep,
01008 SIPTransaction & invite,
01009 SIP_PDU & response);
01010
01011
01012 SIPAck(
01013 SIPTransaction & invite);
01014
01015 protected:
01016 void Construct();
01017
01018 SIPTransaction & transaction;
01019 };
01020
01021
01023
01024
01025
01026 class SIPOptions : public SIPTransaction
01027 {
01028 PCLASSINFO(SIPOptions, SIPTransaction);
01029
01030 public:
01031 SIPOptions(
01032 SIPEndPoint & ep,
01033 OpalTransport & trans,
01034 const SIPURL & address
01035 );
01036 };
01037
01038
01039 #endif // __OPAL_SIPPDU_H
01040
01041
01042