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_SIPPDU_H
00033 #define __OPAL_SIPPDU_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039
00040 #include <ptclib/mime.h>
00041 #include <ptclib/url.h>
00042 #include <sip/sdp.h>
00043
00044
00045 class OpalTransport;
00046 class OpalTransportAddress;
00047 class OpalProductInfo;
00048
00049 class SIPEndPoint;
00050 class SIPConnection;
00051 class SIP_PDU;
00052
00053
00055
00056
00062 class SIPURL : public PURL
00063 {
00064 PCLASSINFO(SIPURL, PURL);
00065 public:
00066 SIPURL();
00067
00070 SIPURL(
00071 const char * cstr,
00072 const char * defaultScheme = NULL
00073 );
00074
00077 SIPURL(
00078 const PString & str,
00079 const char * defaultScheme = NULL
00080 );
00081
00089 SIPURL(
00090 const PString & name,
00091 const OpalTransportAddress & address,
00092 WORD listenerPort = 0
00093 );
00094
00098 PString AsQuotedString() const;
00099
00102 PString GetDisplayName(PBoolean useDefault = PTrue) const;
00103
00104 void SetDisplayName(const PString & str)
00105 { displayName = str; }
00106
00107 OpalTransportAddress GetHostAddress() const;
00108
00112 void AdjustForRequestURI();
00113
00119 PBoolean AdjustToDNS(
00120 PINDEX entry = 0
00121 );
00122
00123 protected:
00142 virtual PBoolean InternalParse(
00143 const char * cstr,
00144 const char * defaultScheme
00145 );
00146
00147 PString displayName;
00148 };
00149
00150
00152
00153
00184 class SIPMIMEInfo : public PMIMEInfo
00185 {
00186 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00187 public:
00188 SIPMIMEInfo(PBoolean compactForm = PFalse);
00189
00190 void SetForm(PBoolean v) { compactForm = v; }
00191
00192 PString GetContentType() const;
00193 void SetContentType(const PString & v);
00194
00195 PString GetContentEncoding() const;
00196 void SetContentEncoding(const PString & v);
00197
00198 PString GetFrom() const;
00199 void SetFrom(const PString & v);
00200
00201 PString GetPAssertedIdentity() const;
00202 void SetPAssertedIdentity(const PString & v);
00203
00204 PString GetPPreferredIdentity() const;
00205 void SetPPreferredIdentity(const PString & v);
00206
00207 PString GetAccept() const;
00208 void SetAccept(const PString & v);
00209
00210 PString GetAcceptEncoding() const;
00211 void SetAcceptEncoding(const PString & v);
00212
00213 PString GetAcceptLanguage() const;
00214 void SetAcceptLanguage(const PString & v);
00215
00216 PString GetAllow() const;
00217 void SetAllow(const PString & v);
00218
00219 PString GetCallID() const;
00220 void SetCallID(const PString & v);
00221
00222 PString GetContact() const;
00223 void SetContact(const PString & v);
00224 void SetContact(const SIPURL & url);
00225
00226 PString GetSubject() const;
00227 void SetSubject(const PString & v);
00228
00229 PString GetTo() const;
00230 void SetTo(const PString & v);
00231
00232 PString GetVia() const;
00233 void SetVia(const PString & v);
00234
00235 PStringList GetViaList() const;
00236 void SetViaList(const PStringList & v);
00237
00238 PString GetReferTo() const;
00239 void SetReferTo(const PString & r);
00240
00241 PString GetReferredBy() const;
00242 void SetReferredBy(const PString & r);
00243
00244 PINDEX GetContentLength() const;
00245 void SetContentLength(PINDEX v);
00246 PBoolean IsContentLengthPresent() const;
00247
00248 PString GetCSeq() const;
00249 void SetCSeq(const PString & v);
00250
00251 PString GetDate() const;
00252 void SetDate(const PString & v);
00253 void SetDate(const PTime & t);
00254 void SetDate(void);
00255
00256 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00257 void SetExpires(unsigned v);
00258
00259 PINDEX GetMaxForwards() const;
00260 void SetMaxForwards(PINDEX v);
00261
00262 PINDEX GetMinExpires() const;
00263 void SetMinExpires(PINDEX v);
00264
00265 PString GetProxyAuthenticate() const;
00266 void SetProxyAuthenticate(const PString & v);
00267
00268 PStringList GetRoute() const;
00269 void SetRoute(const PStringList & v);
00270
00271 PStringList GetRecordRoute() const;
00272 void SetRecordRoute(const PStringList & v);
00273
00274 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00275
00276 PString GetSupported() const;
00277 void SetSupported(const PString & v);
00278
00279 PString GetUnsupported() const;
00280 void SetUnsupported(const PString & v);
00281
00282 PString GetEvent() const;
00283 void SetEvent(const PString & v);
00284
00285 PString GetSubscriptionState() const;
00286 void SetSubscriptionState(const PString & v);
00287
00288 PString GetUserAgent() const;
00289 void SetUserAgent(const PString & v);
00290
00291 PString GetOrganization() const;
00292 void SetOrganization(const PString & v);
00293
00294 void GetProductInfo(OpalProductInfo & info);
00295 void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00296
00297 PString GetWWWAuthenticate() const;
00298 void SetWWWAuthenticate(const PString & v);
00299
00300 PString GetSIPIfMatch() const;
00301 void SetSIPIfMatch(const PString & v);
00302
00303 PString GetSIPETag() const;
00304 void SetSIPETag(const PString & v);
00305
00308 PString GetFieldParameter(const PString &,
00309 const PString &);
00310
00315 void SetFieldParameter(const PString &,
00316 PString &,
00317 const PString &);
00318
00321 PBoolean HasFieldParameter(const PString &,
00322 const PString &);
00323
00324 protected:
00327 PStringList GetRouteList(const char * name) const;
00328
00332 void SetRouteList(const char * name, const PStringList & v);
00333
00336 PString GetFullOrCompact(const char * fullForm, char compactForm) const;
00337
00339 PBoolean compactForm;
00340 };
00341
00342
00344
00345
00346 class SIPAuthentication : public PObject
00347 {
00348 PCLASSINFO(SIPAuthentication, PObject);
00349 public:
00350 SIPAuthentication(
00351 const PString & username = PString::Empty(),
00352 const PString & password = PString::Empty()
00353 );
00354
00355 SIPAuthentication & operator =(const SIPAuthentication & auth)
00356 {
00357 isProxy = auth.isProxy;
00358 authRealm = auth.authRealm;
00359 username = auth.username;
00360 password = auth.password;
00361 nonce = auth.nonce;
00362 algorithm = auth.algorithm;
00363 opaque = auth.opaque;
00364
00365 qopAuth = auth.qopAuth;
00366 qopAuthInt = auth.qopAuthInt;
00367 cnonce = auth.cnonce;
00368 nonceCount.SetValue(auth.nonceCount);
00369
00370 return *this;
00371 }
00372
00373 PBoolean Parse(
00374 const PCaselessString & auth,
00375 PBoolean proxy
00376 );
00377
00378 PBoolean IsValid() const;
00379
00380 PBoolean Authorise(
00381 SIP_PDU & pdu
00382 ) const;
00383
00384 enum Algorithm {
00385 Algorithm_MD5,
00386 NumAlgorithms
00387 };
00388
00389 PBoolean IsProxy() const { return isProxy; }
00390 const PString & GetAuthRealm() const { return authRealm; }
00391 const PString & GetUsername() const { return username; }
00392 const PString & GetPassword() const { return password; }
00393 const PString & GetNonce() const { return nonce; }
00394 Algorithm GetAlgorithm() const { return algorithm; }
00395 const PString & GetOpaque() const { return opaque; }
00396
00397 void SetUsername(const PString & user) { username = user; }
00398 void SetPassword(const PString & pass) { password = pass; }
00399 void SetAuthRealm(const PString & r) { authRealm = r; }
00400
00401 protected:
00402 PBoolean isProxy;
00403 PString authRealm;
00404 PString username;
00405 PString password;
00406 PString nonce;
00407 Algorithm algorithm;
00408 PString opaque;
00409
00410 PBoolean qopAuth;
00411 PBoolean qopAuthInt;
00412 PString cnonce;
00413 mutable PAtomicInteger nonceCount;
00414 };
00415
00416
00418
00419
00425 class SIP_PDU : public PSafeObject
00426 {
00427 PCLASSINFO(SIP_PDU, PSafeObject);
00428 public:
00429 enum Methods {
00430 Method_INVITE,
00431 Method_ACK,
00432 Method_OPTIONS,
00433 Method_BYE,
00434 Method_CANCEL,
00435 Method_REGISTER,
00436 Method_SUBSCRIBE,
00437 Method_NOTIFY,
00438 Method_REFER,
00439 Method_MESSAGE,
00440 Method_INFO,
00441 Method_PING,
00442 Method_PUBLISH,
00443 NumMethods
00444 };
00445
00446 enum StatusCodes {
00447 IllegalStatusCode,
00448
00449 Information_Trying = 100,
00450 Information_Ringing = 180,
00451 Information_CallForwarded = 181,
00452 Information_Queued = 182,
00453 Information_Session_Progress = 183,
00454
00455 Successful_OK = 200,
00456 Successful_Accepted = 202,
00457
00458 Redirection_MultipleChoices = 300,
00459 Redirection_MovedPermanently = 301,
00460 Redirection_MovedTemporarily = 302,
00461 Redirection_UseProxy = 305,
00462 Redirection_AlternativeService = 380,
00463
00464 Failure_BadRequest = 400,
00465 Failure_UnAuthorised = 401,
00466 Failure_PaymentRequired = 402,
00467 Failure_Forbidden = 403,
00468 Failure_NotFound = 404,
00469 Failure_MethodNotAllowed = 405,
00470 Failure_NotAcceptable = 406,
00471 Failure_ProxyAuthenticationRequired = 407,
00472 Failure_RequestTimeout = 408,
00473 Failure_Conflict = 409,
00474 Failure_Gone = 410,
00475 Failure_LengthRequired = 411,
00476 Failure_RequestEntityTooLarge = 413,
00477 Failure_RequestURITooLong = 414,
00478 Failure_UnsupportedMediaType = 415,
00479 Failure_UnsupportedURIScheme = 416,
00480 Failure_BadExtension = 420,
00481 Failure_ExtensionRequired = 421,
00482 Failure_IntervalTooBrief = 423,
00483 Failure_TemporarilyUnavailable = 480,
00484 Failure_TransactionDoesNotExist = 481,
00485 Failure_LoopDetected = 482,
00486 Failure_TooManyHops = 483,
00487 Failure_AddressIncomplete = 484,
00488 Failure_Ambiguous = 485,
00489 Failure_BusyHere = 486,
00490 Failure_RequestTerminated = 487,
00491 Failure_NotAcceptableHere = 488,
00492 Failure_BadEvent = 489,
00493 Failure_RequestPending = 491,
00494 Failure_Undecipherable = 493,
00495
00496 Failure_InternalServerError = 500,
00497 Failure_NotImplemented = 501,
00498 Failure_BadGateway = 502,
00499 Failure_ServiceUnavailable = 503,
00500 Failure_ServerTimeout = 504,
00501 Failure_SIPVersionNotSupported = 505,
00502 Failure_MessageTooLarge = 513,
00503
00504 GlobalFailure_BusyEverywhere = 600,
00505 GlobalFailure_Decline = 603,
00506 GlobalFailure_DoesNotExistAnywhere = 604,
00507 GlobalFailure_NotAcceptable = 606,
00508
00509 MaxStatusCode = 699
00510 };
00511
00512 static const char * GetStatusCodeDescription (int code);
00513
00514 enum {
00515 MaxSize = 65535
00516 };
00517
00518 SIP_PDU();
00519
00522 SIP_PDU(
00523 Methods method,
00524 const SIPURL & dest,
00525 const PString & to,
00526 const PString & from,
00527 const PString & callID,
00528 unsigned cseq,
00529 const OpalTransportAddress & via
00530 );
00533 SIP_PDU(
00534 Methods method,
00535 SIPConnection & connection,
00536 const OpalTransport & transport
00537 );
00538
00542 SIP_PDU(
00543 const SIP_PDU & request,
00544 StatusCodes code,
00545 const char * contact = NULL,
00546 const char * extra = NULL
00547 );
00548 SIP_PDU(const SIP_PDU &);
00549 SIP_PDU & operator=(const SIP_PDU &);
00550 ~SIP_PDU();
00551
00552 void PrintOn(
00553 ostream & strm
00554 ) const;
00555
00556 void Construct(
00557 Methods method
00558 );
00559 void Construct(
00560 Methods method,
00561 const SIPURL & dest,
00562 const PString & to,
00563 const PString & from,
00564 const PString & callID,
00565 unsigned cseq,
00566 const OpalTransportAddress & via
00567 );
00568 void Construct(
00569 Methods method,
00570 SIPConnection & connection,
00571 const OpalTransport & transport
00572 );
00573
00578 PBoolean SetRoute(const PStringList & routeSet);
00579
00582 void SetAllow(void);
00583
00586 void AdjustVia(OpalTransport & transport);
00587
00591 OpalTransportAddress GetViaAddress(OpalEndPoint &);
00592
00596 OpalTransportAddress GetSendAddress(const PStringList & routeSet);
00597
00600 PBoolean Read(
00601 OpalTransport & transport
00602 );
00603
00606 PBoolean Write(
00607 OpalTransport & transport,
00608 const OpalTransportAddress & remoteAddress = OpalTransportAddress()
00609 );
00610
00614 PString Build();
00615
00616 PString GetTransactionID() const;
00617
00618 Methods GetMethod() const { return method; }
00619 StatusCodes GetStatusCode () const { return statusCode; }
00620 const SIPURL & GetURI() const { return uri; }
00621 unsigned GetVersionMajor() const { return versionMajor; }
00622 unsigned GetVersionMinor() const { return versionMinor; }
00623 const PString & GetEntityBody() const { return entityBody; }
00624 PString & GetEntityBody() { return entityBody; }
00625 const PString & GetInfo() const { return info; }
00626 const SIPMIMEInfo & GetMIME() const { return mime; }
00627 SIPMIMEInfo & GetMIME() { return mime; }
00628 PBoolean HasSDP() const { return sdp != NULL; }
00629 SDPSessionDescription & GetSDP() const { return *PAssertNULL(sdp); }
00630 void SetURI(const SIPURL & newuri) { uri = newuri; }
00631 void SetSDP(SDPSessionDescription * s) { sdp = s; }
00632 void SetSDP(const SDPSessionDescription & s) { sdp = new SDPSessionDescription(s); }
00633
00634 protected:
00635
00636 Methods method;
00637 StatusCodes statusCode;
00638 SIPURL uri;
00639 unsigned versionMajor;
00640 unsigned versionMinor;
00641 PString info;
00642 SIPMIMEInfo mime;
00643 PString entityBody;
00644
00645 OpalTransportAddress lastTransportAddress;
00646 SDPSessionDescription * sdp;
00647 };
00648
00649
00650 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00651
00652
00653 #if PTRACING
00654 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00655 #endif
00656
00657
00659
00660
00671 class SIPTransaction : public SIP_PDU
00672 {
00673 PCLASSINFO(SIPTransaction, SIP_PDU);
00674 public:
00675 SIPTransaction(
00676 SIPEndPoint & endpoint,
00677 OpalTransport & transport,
00678 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00679 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00680 );
00684 SIPTransaction(
00685 SIPConnection & connection,
00686 OpalTransport & transport,
00687 Methods method = NumMethods
00688 );
00689 ~SIPTransaction();
00690
00691 PBoolean Start();
00692 PBoolean IsInProgress() const { return state == Trying || state == Proceeding; }
00693 PBoolean IsFailed() const { return state > Terminated_Success; }
00694 PBoolean IsCompleted() const { return state >= Completed; }
00695 PBoolean IsCanceled() const { return state == Cancelling || state == Terminated_Cancelled || state == Terminated_Aborted; }
00696 PBoolean IsTerminated() const { return state >= Terminated_Success; }
00697
00698 void WaitForCompletion();
00699 PBoolean Cancel();
00700 void Abort();
00701
00702 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00703 virtual PBoolean OnCompleted(SIP_PDU & response);
00704
00705 OpalTransport & GetTransport() const { return transport; }
00706 SIPConnection * GetConnection() const { return connection; }
00707 PString GetInterface() const { return localInterface; }
00708
00709 protected:
00710 void Construct(
00711 const PTimeInterval & minRetryTime = PMaxTimeInterval,
00712 const PTimeInterval & maxRetryTime = PMaxTimeInterval
00713 );
00714 bool SendPDU(SIP_PDU & pdu);
00715 bool ResendCANCEL();
00716
00717 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00718 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00719
00720 enum States {
00721 NotStarted,
00722 Trying,
00723 Aborting,
00724 Proceeding,
00725 Cancelling,
00726 Completed,
00727 Terminated_Success,
00728 Terminated_Timeout,
00729 Terminated_RetriesExceeded,
00730 Terminated_TransportError,
00731 Terminated_Cancelled,
00732 Terminated_Aborted,
00733 NumStates
00734 };
00735 virtual void SetTerminated(States newState);
00736
00737 SIPEndPoint & endpoint;
00738 OpalTransport & transport;
00739 PSafePtr<SIPConnection> connection;
00740 PTimeInterval retryTimeoutMin;
00741 PTimeInterval retryTimeoutMax;
00742
00743 States state;
00744 unsigned retry;
00745 PTimer retryTimer;
00746 PTimer completionTimer;
00747 PSyncPoint completed;
00748 PString localInterface;
00749 };
00750
00751
00753
00754
00760 class SIPInvite : public SIPTransaction
00761 {
00762 PCLASSINFO(SIPInvite, SIPTransaction);
00763 public:
00764 SIPInvite(
00765 SIPConnection & connection,
00766 OpalTransport & transport
00767 );
00768 SIPInvite(
00769 SIPConnection & connection,
00770 OpalTransport & transport,
00771 RTP_SessionManager & sm
00772 );
00773
00774 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00775
00776 RTP_SessionManager & GetSessionManager() { return rtpSessions; }
00777
00778 protected:
00779 RTP_SessionManager rtpSessions;
00780 };
00781
00782
00784
00785 class SIPRegister : public SIPTransaction
00786 {
00787 PCLASSINFO(SIPRegister, SIPTransaction);
00788 public:
00789 struct Params {
00790 Params();
00791
00792 PString m_addressOfRecord;
00793 PString m_contactAddress;
00794 PString m_authID;
00795 PString m_password;
00796 PString m_realm;
00797 unsigned m_expire;
00798 PTimeInterval m_minRetryTime;
00799 PTimeInterval m_maxRetryTime;
00800 };
00801
00802 SIPRegister(
00803 SIPEndPoint & endpoint,
00804 OpalTransport & transport,
00805 const PStringList & routeSet,
00806 const PString & id,
00807 const Params & params
00808 );
00809 };
00810
00811
00813
00814 class SIPSubscribe : public SIPTransaction
00815 {
00816 PCLASSINFO(SIPSubscribe, SIPTransaction);
00817 public:
00820 enum SubscribeType {
00821 Unknown,
00822 MessageSummary,
00823 Presence
00824 };
00825
00828 enum MWIType {
00829
00830 VoiceMessage,
00831 FaxMessage,
00832 PagerMessage,
00833 MultimediaMessage,
00834 TextMessage,
00835 None
00836 };
00837 SIPSubscribe(
00838 SIPEndPoint & ep,
00839 OpalTransport & trans,
00840 SIPSubscribe::SubscribeType & type,
00841 const PStringList & routeSet,
00842 const SIPURL & targetAddress,
00843 const PString & remotePartyAddress,
00844 const PString & localPartyAddress,
00845 const PString & id,
00846 const unsigned & cseq,
00847 unsigned expires
00848 );
00849 };
00850
00851
00853
00854 class SIPPublish : public SIPTransaction
00855 {
00856 PCLASSINFO(SIPPublish, SIPTransaction);
00857 public:
00858 SIPPublish(
00859 SIPEndPoint & ep,
00860 OpalTransport & trans,
00861 const PStringList & routeSet,
00862 const SIPURL & targetAddress,
00863 const PString & sipIfMatch,
00864 const PString & body,
00865 unsigned expires
00866 );
00867 };
00868
00869
00871
00872 class SIPRefer : public SIPTransaction
00873 {
00874 PCLASSINFO(SIPRefer, SIPTransaction);
00875 public:
00876 SIPRefer(
00877 SIPConnection & connection,
00878 OpalTransport & transport,
00879 const PString & refer
00880 );
00881 SIPRefer(
00882 SIPConnection & connection,
00883 OpalTransport & transport,
00884 const PString & refer,
00885 const PString & referred_by
00886 );
00887 protected:
00888 void Construct(
00889 SIPConnection & connection,
00890 OpalTransport & transport,
00891 const PString & refer,
00892 const PString & referred_by = PString::Empty()
00893 );
00894 };
00895
00896
00898
00899
00900
00901
00902 class SIPReferNotify : public SIPTransaction
00903 {
00904 PCLASSINFO(SIPReferNotify, SIPTransaction);
00905 public:
00906 SIPReferNotify(
00907 SIPConnection & connection,
00908 OpalTransport & transport,
00909 StatusCodes code
00910 );
00911 };
00912
00913
00915
00916
00917
00918 class SIPMessage : public SIPTransaction
00919 {
00920 PCLASSINFO(SIPMessage, SIPTransaction);
00921
00922 public:
00923 SIPMessage(
00924 SIPEndPoint & ep,
00925 OpalTransport & trans,
00926 const SIPURL & to,
00927 const PStringList & routeSet,
00928 const PString & body
00929 );
00930 };
00931
00932
00934
00935
00936
00937
00938 class SIPAck : public SIP_PDU
00939 {
00940 PCLASSINFO(SIPAck, SIP_PDU);
00941 public:
00942
00943 SIPAck(
00944 SIPEndPoint & ep,
00945 SIPTransaction & invite,
00946 SIP_PDU & response);
00947
00948
00949 SIPAck(
00950 SIPTransaction & invite);
00951
00952 protected:
00953 void Construct();
00954
00955 SIPTransaction & transaction;
00956 };
00957
00958
00960
00961
00962
00963 class SIPOptions : public SIPTransaction
00964 {
00965 PCLASSINFO(SIPOptions, SIPTransaction);
00966
00967 public:
00968 SIPOptions(
00969 SIPEndPoint & ep,
00970 OpalTransport & trans,
00971 const SIPURL & address
00972 );
00973 };
00974
00975
00977
00978
00979
00980 class SIPPing : public SIPTransaction
00981 {
00982 PCLASSINFO(SIPPing, SIPTransaction);
00983
00984 public:
00985 SIPPing(
00986 SIPEndPoint & ep,
00987 OpalTransport & trans,
00988 const SIPURL & address,
00989 const PString & body = PString::Empty()
00990 );
00991 };
00992
00993
00994 #endif // __OPAL_SIPPDU_H
00995
00996
00997