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_SIP_SIPPDU_H
00033 #define OPAL_SIP_SIPPDU_H
00034
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038
00039 #include <opal/buildopts.h>
00040
00041 #if OPAL_SIP
00042
00043 #include <ptclib/mime.h>
00044 #include <ptclib/url.h>
00045 #include <ptclib/http.h>
00046 #include <sip/sdp.h>
00047 #include <opal/rtpconn.h>
00048
00049
00050 class OpalTransport;
00051 class OpalTransportAddress;
00052 class OpalProductInfo;
00053
00054 class SIPEndPoint;
00055 class SIPConnection;
00056 class SIP_PDU;
00057 class SIPSubscribeHandler;
00058 class SIPDialogContext;
00059
00060
00062
00063
00069 class SIPURL : public PURL
00070 {
00071 PCLASSINFO(SIPURL, PURL);
00072 public:
00073 SIPURL();
00074
00077 SIPURL(
00078 const char * cstr,
00079 const char * defaultScheme = NULL
00080 );
00081
00084 SIPURL(
00085 const PString & str,
00086 const char * defaultScheme = NULL
00087 );
00088
00096 SIPURL(
00097 const PString & name,
00098 const OpalTransportAddress & address,
00099 WORD listenerPort = 0
00100 );
00101
00102 SIPURL(
00103 const OpalTransportAddress & _address,
00104 WORD listenerPort = 0
00105 );
00106
00115 virtual Comparison Compare(
00116 const PObject & obj
00117 ) const;
00118
00122 PString AsQuotedString() const;
00123
00126 PString GetDisplayName(PBoolean useDefault = PTrue) const;
00127
00128 void SetDisplayName(const PString & str)
00129 { displayName = str; }
00130
00133 PString GetFieldParameters() const { return fieldParameters; }
00134
00137 void SetFieldParameters(const PString & str ) { fieldParameters = str; }
00138
00141 OpalTransportAddress GetHostAddress() const;
00142
00143 enum UsageContext {
00144 ExternalURI,
00145 RequestURI,
00146 ToURI,
00147 FromURI,
00148 ContactURI,
00149 RouteURI,
00150 RegisterURI
00151 };
00152
00158 void Sanitise(
00159 UsageContext context
00160 );
00161
00167 PBoolean AdjustToDNS(
00168 PINDEX entry = 0
00169 );
00170
00172 static PString GenerateTag();
00173
00175 void SetTag(
00176 const PString & tag = GenerateTag()
00177 );
00178
00179 protected:
00180 void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0);
00181
00200 virtual PBoolean InternalParse(
00201 const char * cstr,
00202 const char * defaultScheme
00203 );
00204
00205 PString displayName;
00206 PString fieldParameters;
00207 };
00208
00209
00211
00212
00243 class SIPMIMEInfo : public PMIMEInfo
00244 {
00245 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00246 public:
00247 SIPMIMEInfo(bool compactForm = false);
00248
00249 virtual void PrintOn(ostream & strm) const;
00250 virtual void ReadFrom(istream & strm);
00251
00252 void SetCompactForm(bool form) { compactForm = form; }
00253
00254 PCaselessString GetContentType(bool includeParameters = false) const;
00255 void SetContentType(const PString & v);
00256
00257 PCaselessString GetContentEncoding() const;
00258 void SetContentEncoding(const PString & v);
00259
00260 PString GetFrom() const;
00261 void SetFrom(const PString & v);
00262
00263 PString GetPAssertedIdentity() const;
00264 void SetPAssertedIdentity(const PString & v);
00265
00266 PString GetPPreferredIdentity() const;
00267 void SetPPreferredIdentity(const PString & v);
00268
00269 PString GetAccept() const;
00270 void SetAccept(const PString & v);
00271
00272 PString GetAcceptEncoding() const;
00273 void SetAcceptEncoding(const PString & v);
00274
00275 PString GetAcceptLanguage() const;
00276 void SetAcceptLanguage(const PString & v);
00277
00278 PString GetAllow() const;
00279 void SetAllow(const PString & v);
00280
00281 PString GetCallID() const;
00282 void SetCallID(const PString & v);
00283
00284 PString GetContact() const;
00285 bool GetContacts(std::set<SIPURL> & contacts) const;
00286 void SetContact(const PString & v);
00287
00288 PString GetSubject() const;
00289 void SetSubject(const PString & v);
00290
00291 PString GetTo() const;
00292 void SetTo(const PString & v);
00293
00294 PString GetVia() const;
00295 void SetVia(const PString & v);
00296
00297 PStringList GetViaList() const;
00298 void SetViaList(const PStringList & v);
00299
00300 PString GetReferTo() const;
00301 void SetReferTo(const PString & r);
00302
00303 PString GetReferredBy() const;
00304 void SetReferredBy(const PString & r);
00305
00306 PINDEX GetContentLength() const;
00307 void SetContentLength(PINDEX v);
00308 PBoolean IsContentLengthPresent() const;
00309
00310 PString GetCSeq() const;
00311 void SetCSeq(const PString & v);
00312
00313 PString GetDate() const;
00314 void SetDate(const PString & v);
00315 void SetDate(const PTime & t);
00316 void SetDate(void);
00317
00318 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00319 void SetExpires(unsigned v);
00320
00321 PINDEX GetMaxForwards() const;
00322 void SetMaxForwards(PINDEX v);
00323
00324 PINDEX GetMinExpires() const;
00325 void SetMinExpires(PINDEX v);
00326
00327 PString GetProxyAuthenticate() const;
00328 void SetProxyAuthenticate(const PString & v);
00329
00330 PStringList GetRoute() const;
00331 void SetRoute(const PString & v);
00332 void SetRoute(const PStringList & v);
00333
00334 PStringList GetRecordRoute(bool reversed) const;
00335 void SetRecordRoute(const PStringList & v);
00336
00337 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00338
00339 PString GetSupported() const;
00340 void SetSupported(const PString & v);
00341
00342 PString GetUnsupported() const;
00343 void SetUnsupported(const PString & v);
00344
00345 PString GetEvent() const;
00346 void SetEvent(const PString & v);
00347
00348 PCaselessString GetSubscriptionState(PStringToString & info) const;
00349 void SetSubscriptionState(const PString & v);
00350
00351 PString GetUserAgent() const;
00352 void SetUserAgent(const PString & v);
00353
00354 PString GetOrganization() const;
00355 void SetOrganization(const PString & v);
00356
00357 void GetProductInfo(OpalProductInfo & info) const;
00358 void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00359
00360 PString GetWWWAuthenticate() const;
00361 void SetWWWAuthenticate(const PString & v);
00362
00363 PString GetSIPIfMatch() const;
00364 void SetSIPIfMatch(const PString & v);
00365
00366 PString GetSIPETag() const;
00367 void SetSIPETag(const PString & v);
00368
00369 PString GetRequire() const;
00370 void SetRequire(const PString & v, bool overwrite);
00371
00372 void GetAlertInfo(PString & info, int & appearance);
00373 void SetAlertInfo(const PString & info, int appearance);
00374
00375 PString GetAllowEvents() const;
00376 void SetAllowEvents(const PString & v);
00377
00380 PString GetFieldParameter(
00381 const PString & fieldName,
00382 const PString & paramName,
00383 const PString & defaultValue = PString::Empty()
00384 ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
00385
00390 void SetFieldParameter(
00391 const PString & fieldName,
00392 const PString & paramName,
00393 const PString & newValue
00394 ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
00395
00398 static PString ExtractFieldParameter(
00399 const PString & fieldValue,
00400 const PString & paramName,
00401 const PString & defaultValue = PString::Empty()
00402 );
00403
00408 static PString InsertFieldParameter(
00409 const PString & fieldValue,
00410 const PString & paramName,
00411 const PString & newValue
00412 );
00413
00414 protected:
00417 PStringList GetRouteList(const char * name, bool reversed) const;
00418
00422 void SetRouteList(const char * name, const PStringList & v);
00423
00425 bool compactForm;
00426 };
00427
00428
00430
00431
00432 typedef PHTTPClientAuthentication SIPAuthentication;
00433
00434 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject
00435 {
00436 public:
00437 SIPAuthenticator(SIP_PDU & pdu);
00438 virtual PMIMEInfo & GetMIME();
00439 virtual PString GetURI();
00440 virtual PString GetEntityBody();
00441 virtual PString GetMethod();
00442
00443 protected:
00444 SIP_PDU & m_pdu;
00445 };
00446
00447
00448
00450
00451
00457 class SIP_PDU : public PSafeObject
00458 {
00459 PCLASSINFO(SIP_PDU, PSafeObject);
00460 public:
00461 enum Methods {
00462 Method_INVITE,
00463 Method_ACK,
00464 Method_OPTIONS,
00465 Method_BYE,
00466 Method_CANCEL,
00467 Method_REGISTER,
00468 Method_SUBSCRIBE,
00469 Method_NOTIFY,
00470 Method_REFER,
00471 Method_MESSAGE,
00472 Method_INFO,
00473 Method_PING,
00474 Method_PUBLISH,
00475 NumMethods
00476 };
00477
00478 enum StatusCodes {
00479 IllegalStatusCode,
00480 Local_TransportError,
00481 Local_BadTransportAddress,
00482 Local_Timeout,
00483
00484 Information_Trying = 100,
00485 Information_Ringing = 180,
00486 Information_CallForwarded = 181,
00487 Information_Queued = 182,
00488 Information_Session_Progress = 183,
00489
00490 Successful_OK = 200,
00491 Successful_Accepted = 202,
00492
00493 Redirection_MultipleChoices = 300,
00494 Redirection_MovedPermanently = 301,
00495 Redirection_MovedTemporarily = 302,
00496 Redirection_UseProxy = 305,
00497 Redirection_AlternativeService = 380,
00498
00499 Failure_BadRequest = 400,
00500 Failure_UnAuthorised = 401,
00501 Failure_PaymentRequired = 402,
00502 Failure_Forbidden = 403,
00503 Failure_NotFound = 404,
00504 Failure_MethodNotAllowed = 405,
00505 Failure_NotAcceptable = 406,
00506 Failure_ProxyAuthenticationRequired = 407,
00507 Failure_RequestTimeout = 408,
00508 Failure_Conflict = 409,
00509 Failure_Gone = 410,
00510 Failure_LengthRequired = 411,
00511 Failure_RequestEntityTooLarge = 413,
00512 Failure_RequestURITooLong = 414,
00513 Failure_UnsupportedMediaType = 415,
00514 Failure_UnsupportedURIScheme = 416,
00515 Failure_BadExtension = 420,
00516 Failure_ExtensionRequired = 421,
00517 Failure_IntervalTooBrief = 423,
00518 Failure_TemporarilyUnavailable = 480,
00519 Failure_TransactionDoesNotExist = 481,
00520 Failure_LoopDetected = 482,
00521 Failure_TooManyHops = 483,
00522 Failure_AddressIncomplete = 484,
00523 Failure_Ambiguous = 485,
00524 Failure_BusyHere = 486,
00525 Failure_RequestTerminated = 487,
00526 Failure_NotAcceptableHere = 488,
00527 Failure_BadEvent = 489,
00528 Failure_RequestPending = 491,
00529 Failure_Undecipherable = 493,
00530
00531 Failure_InternalServerError = 500,
00532 Failure_NotImplemented = 501,
00533 Failure_BadGateway = 502,
00534 Failure_ServiceUnavailable = 503,
00535 Failure_ServerTimeout = 504,
00536 Failure_SIPVersionNotSupported = 505,
00537 Failure_MessageTooLarge = 513,
00538
00539 GlobalFailure_BusyEverywhere = 600,
00540 GlobalFailure_Decline = 603,
00541 GlobalFailure_DoesNotExistAnywhere = 604,
00542 GlobalFailure_NotAcceptable = 606,
00543
00544 MaxStatusCode = 699
00545 };
00546
00547 static const char * GetStatusCodeDescription(int code);
00548 friend ostream & operator<<(ostream & strm, StatusCodes status);
00549
00550 enum {
00551 MaxSize = 65535
00552 };
00553
00554 SIP_PDU(
00555 Methods method = SIP_PDU::NumMethods
00556 );
00557
00561 SIP_PDU(
00562 const SIP_PDU & request,
00563 StatusCodes code,
00564 const char * contact = NULL,
00565 const char * extra = NULL,
00566 const SDPSessionDescription * sdp = NULL
00567 );
00568
00569 SIP_PDU(const SIP_PDU &);
00570 SIP_PDU & operator=(const SIP_PDU &);
00571 ~SIP_PDU();
00572
00573 void PrintOn(
00574 ostream & strm
00575 ) const;
00576
00577 void InitialiseHeaders(
00578 const SIPURL & dest,
00579 const SIPURL & to,
00580 const SIPURL & from,
00581 const PString & callID,
00582 unsigned cseq,
00583 const PString & via
00584 );
00585 void InitialiseHeaders(
00586 SIPDialogContext & dialog,
00587 const PString & via = PString::Empty()
00588 );
00589 void InitialiseHeaders(
00590 SIPConnection & connection,
00591 const OpalTransport & transport
00592 );
00593
00598 bool SetRoute(const PStringList & routeSet);
00599 bool SetRoute(const SIPURL & proxy);
00600
00603 void SetAllow(unsigned bitmask);
00604
00607 void AdjustVia(OpalTransport & transport);
00608
00609 PString CreateVia(
00610 SIPEndPoint & endpoint,
00611 const OpalTransport & transport,
00612 SIPConnection * connection = NULL
00613 );
00614
00617 PBoolean Read(
00618 OpalTransport & transport
00619 );
00620
00623 PBoolean Write(
00624 OpalTransport & transport,
00625 const OpalTransportAddress & remoteAddress = OpalTransportAddress(),
00626 const PString & localInterface = PString::Empty()
00627 );
00628
00631 bool SendResponse(
00632 OpalTransport & transport,
00633 StatusCodes code,
00634 SIPEndPoint * endpoint = NULL,
00635 const char * contact = NULL,
00636 const char * extra = NULL
00637 );
00638 bool SendResponse(
00639 OpalTransport & transport,
00640 SIP_PDU & response,
00641 SIPEndPoint * endpoint = NULL
00642 );
00643
00647 PString Build();
00648
00649 PString GetTransactionID() const;
00650
00651 Methods GetMethod() const { return m_method; }
00652 StatusCodes GetStatusCode () const { return m_statusCode; }
00653 void SetStatusCode (StatusCodes c) { m_statusCode = c; }
00654 const SIPURL & GetURI() const { return m_uri; }
00655 unsigned GetVersionMajor() const { return m_versionMajor; }
00656 unsigned GetVersionMinor() const { return m_versionMinor; }
00657 const PString & GetEntityBody() const { return m_entityBody; }
00658 void SetEntityBody(const PString & body) { m_entityBody = body; }
00659 const PString & GetInfo() const { return m_info; }
00660 void SetInfo(const PString & info) { m_info = info; }
00661 const SIPMIMEInfo & GetMIME() const { return m_mime; }
00662 SIPMIMEInfo & GetMIME() { return m_mime; }
00663 void SetURI(const SIPURL & newuri) { m_uri = newuri; }
00664 SDPSessionDescription * GetSDP();
00665 void SetSDP(SDPSessionDescription * sdp);
00666
00667 protected:
00668 Methods m_method;
00669 StatusCodes m_statusCode;
00670 SIPURL m_uri;
00671 unsigned m_versionMajor;
00672 unsigned m_versionMinor;
00673 PString m_info;
00674 SIPMIMEInfo m_mime;
00675 PString m_entityBody;
00676
00677 SDPSessionDescription * m_SDP;
00678
00679 mutable PString m_transactionID;
00680
00681 bool m_usePeerTransportAddress;
00682 };
00683
00684
00685 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00686
00687
00688 #if PTRACING
00689 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00690 #endif
00691
00692
00694
00695
00698 class SIPDialogContext
00699 {
00700 public:
00701 SIPDialogContext();
00702
00703 PString AsString() const;
00704 bool FromString(
00705 const PString & str
00706 );
00707
00708 const PString & GetCallID() const { return m_callId; }
00709 void SetCallID(const PString & id) { m_callId = id; }
00710
00711 const SIPURL & GetRequestURI() const { return m_requestURI; }
00712 void SetRequestURI(const SIPURL & url) { m_requestURI = url; }
00713 bool SetRequestURI(const PString & uri) { return m_requestURI.Parse(uri); }
00714
00715 const PString & GetLocalTag() const { return m_localTag; }
00716 void SetLocalTag(const PString & tag) { m_localTag = tag; }
00717
00718 const SIPURL & GetLocalURI() const { return m_localURI; }
00719 void SetLocalURI(const SIPURL & url);
00720 bool SetLocalURI(const PString & uri);
00721
00722 const PString & GetRemoteTag() const { return m_remoteTag; }
00723 void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
00724
00725 const SIPURL & GetRemoteURI() const { return m_remoteURI; }
00726 void SetRemoteURI(const SIPURL & url);
00727 bool SetRemoteURI(const PString & uri);
00728
00729 const PStringList & GetRouteSet() const { return m_routeSet; }
00730 void SetRouteSet(const PStringList & routes) { m_routeSet = routes; }
00731
00732 const SIPURL & GetProxy() const { return m_proxy; }
00733 void SetProxy(const SIPURL & proxy, bool addToRouteSet);
00734
00735 void Update(const SIP_PDU & response);
00736
00737 unsigned GetNextCSeq(unsigned inc = 1) { return m_lastSentCSeq += inc; }
00738 bool IsDuplicateCSeq(unsigned sequenceNumber);
00739
00740 bool IsEstablished() const
00741 {
00742 return !m_callId.IsEmpty() &&
00743 !m_requestURI.IsEmpty() &&
00744 !m_localTag.IsEmpty() &&
00745 !m_remoteTag.IsEmpty();
00746 }
00747
00748 bool UsePeerTransportAddress() const { return m_usePeerTransportAddress; }
00749
00750 protected:
00751 PString m_callId;
00752 SIPURL m_requestURI;
00753 SIPURL m_localURI;
00754 PString m_localTag;
00755 SIPURL m_remoteURI;
00756 PString m_remoteTag;
00757 PStringList m_routeSet;
00758 unsigned m_lastSentCSeq;
00759 unsigned m_lastReceivedCSeq;
00760 bool m_usePeerTransportAddress;
00761 SIPURL m_proxy;
00762 };
00763
00764
00766
00767 struct SIPParameters
00768 {
00769 SIPParameters(
00770 const PString & aor = PString::Empty(),
00771 const PString & remote = PString::Empty()
00772 );
00773
00774 void Normalise(
00775 const PString & defaultUser,
00776 const PTimeInterval & defaultExpire
00777 );
00778
00779 PCaselessString m_remoteAddress;
00780 PCaselessString m_localAddress;
00781 PCaselessString m_proxyAddress;
00782 PCaselessString m_addressOfRecord;
00783 PCaselessString m_contactAddress;
00784 PString m_authID;
00785 PString m_password;
00786 PString m_realm;
00787 unsigned m_expire;
00788 unsigned m_restoreTime;
00789 PTimeInterval m_minRetryTime;
00790 PTimeInterval m_maxRetryTime;
00791 void * m_userData;
00792 };
00793
00794
00795 #if PTRACING
00796 ostream & operator<<(ostream & strm, const SIPParameters & params);
00797 #endif
00798
00799
00801
00802
00813 class SIPTransaction : public SIP_PDU
00814 {
00815 PCLASSINFO(SIPTransaction, SIP_PDU);
00816 public:
00817 SIPTransaction(
00818 Methods method,
00819 SIPEndPoint & endpoint,
00820 OpalTransport & transport
00821 );
00825 SIPTransaction(
00826 Methods method,
00827 SIPConnection & connection
00828 );
00829 ~SIPTransaction();
00830
00831 PBoolean Start();
00832 bool IsTrying() const { return m_state == Trying; }
00833 bool IsProceeding() const { return m_state == Proceeding; }
00834 bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
00835 bool IsFailed() const { return m_state > Terminated_Success; }
00836 bool IsCompleted() const { return m_state >= Completed; }
00837 bool IsCanceled() const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
00838 bool IsTerminated() const { return m_state >= Terminated_Success; }
00839
00840 void WaitForTermination();
00841 PBoolean Cancel();
00842 void Abort();
00843
00844 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00845 virtual PBoolean OnCompleted(SIP_PDU & response);
00846
00847 OpalTransport & GetTransport() const { return m_transport; }
00848 SIPConnection * GetConnection() const { return m_connection; }
00849 PString GetInterface() const { return m_localInterface; }
00850
00851 static PString GenerateCallID();
00852
00853 protected:
00854 bool SendPDU(SIP_PDU & pdu);
00855 bool ResendCANCEL();
00856 void SetParameters(const SIPParameters & params);
00857 void SetContact(const SIPURL & uri);
00858
00859 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00860 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00861
00862 enum States {
00863 NotStarted,
00864 Trying,
00865 Proceeding,
00866 Cancelling,
00867 Completed,
00868 Terminated_Success,
00869 Terminated_Timeout,
00870 Terminated_RetriesExceeded,
00871 Terminated_TransportError,
00872 Terminated_Cancelled,
00873 Terminated_Aborted,
00874 NumStates
00875 };
00876 virtual void SetTerminated(States newState);
00877
00878 SIPEndPoint & m_endpoint;
00879 OpalTransport & m_transport;
00880 PSafePtr<SIPConnection> m_connection;
00881 PTimeInterval m_retryTimeoutMin;
00882 PTimeInterval m_retryTimeoutMax;
00883
00884 States m_state;
00885 unsigned m_retry;
00886 PTimer m_retryTimer;
00887 PTimer m_completionTimer;
00888 PSyncPoint m_terminated;
00889
00890 PString m_localInterface;
00891 OpalTransportAddress m_remoteAddress;
00892 };
00893
00894
00895 #define OPAL_PROXY_PARAM "OPAL-proxy"
00896 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
00897
00898
00900
00901
00907 class SIPInvite : public SIPTransaction
00908 {
00909 PCLASSINFO(SIPInvite, SIPTransaction);
00910 public:
00911 SIPInvite(
00912 SIPConnection & connection,
00913 const OpalRTPSessionManager & sm
00914 );
00915
00916 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00917
00918 const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; }
00919 OpalRTPSessionManager & GetSessionManager() { return m_rtpSessions; }
00920
00921 protected:
00922 OpalRTPSessionManager m_rtpSessions;
00923 };
00924
00925
00927
00928 class SIPRegister : public SIPTransaction
00929 {
00930 PCLASSINFO(SIPRegister, SIPTransaction);
00931 public:
00932 enum CompatibilityModes {
00933 e_FullyCompliant,
00936 e_CannotRegisterMultipleContacts,
00940 e_CannotRegisterPrivateContacts
00944 };
00945
00947 struct Params : public SIPParameters {
00948 Params()
00949 : m_registrarAddress(m_remoteAddress)
00950 , m_compatibility(SIPRegister::e_FullyCompliant)
00951 { }
00952
00953 Params(const Params & param)
00954 : SIPParameters(param)
00955 , m_registrarAddress(m_remoteAddress)
00956 , m_compatibility(param.m_compatibility)
00957 { }
00958
00959 PCaselessString & m_registrarAddress;
00960 CompatibilityModes m_compatibility;
00961 };
00962
00963 SIPRegister(
00964 SIPEndPoint & endpoint,
00965 OpalTransport & transport,
00966 const PString & callId,
00967 unsigned cseq,
00968 const Params & params
00969 );
00970 };
00971
00972
00973 #if PTRACING
00974 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
00975 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
00976 #endif
00977
00978
00980
00981 class SIPSubscribe : public SIPTransaction
00982 {
00983 PCLASSINFO(SIPSubscribe, SIPTransaction);
00984 public:
00987 enum PredefinedPackages {
00988 MessageSummary,
00989 Presence,
00990 Dialog,
00991
00992 NumPredefinedPackages,
00993
00994 Watcher = 0x8000,
00995
00996 MessageSummaryWatcher = Watcher|MessageSummary,
00997 PresenceWatcher = Watcher|Presence,
00998 DialogWatcher = Watcher|Dialog,
00999
01000 PackageMask = Watcher-1
01001 };
01002 friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
01003
01004 class EventPackage : public PCaselessString
01005 {
01006 PCLASSINFO(EventPackage, PCaselessString);
01007 public:
01008 EventPackage(PredefinedPackages = NumPredefinedPackages);
01009 explicit EventPackage(const PString & str) : PCaselessString(str) { }
01010 explicit EventPackage(const char * str) : PCaselessString(str) { }
01011
01012 EventPackage & operator=(PredefinedPackages pkg);
01013 EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
01014 EventPackage & operator=(const char * str) { PCaselessString::operator=(str); return *this; }
01015
01016 bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
01017 bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01018 bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01019 virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01020
01021 bool IsWatcher() const;
01022 };
01023
01025 struct SubscriptionStatus {
01026 SIPSubscribeHandler * m_handler;
01027 PString m_addressofRecord;
01028 bool m_wasSubscribing;
01029 bool m_reSubscribing;
01030 SIP_PDU::StatusCodes m_reason;
01031 OpalProductInfo m_productInfo;
01032 void * m_userData;
01033 };
01034
01035 struct NotifyCallbackInfo {
01036 NotifyCallbackInfo(
01037 SIPEndPoint & ep,
01038 OpalTransport & trans,
01039 SIP_PDU & notify,
01040 SIP_PDU & response
01041 );
01042
01043 bool SendResponse(
01044 SIP_PDU::StatusCodes status,
01045 const char * extra = NULL
01046 );
01047
01048 SIPEndPoint & m_endpoint;
01049 OpalTransport & m_transport;
01050 SIP_PDU & m_notify;
01051 SIP_PDU & m_response;
01052 bool m_sendResponse;
01053 };
01054
01055 struct Params : public SIPParameters
01056 {
01057 Params(PredefinedPackages pkg = NumPredefinedPackages)
01058 : m_agentAddress(m_remoteAddress)
01059 , m_eventPackage(pkg)
01060 , m_eventList(false)
01061 { }
01062
01063 Params(const Params & param)
01064 : SIPParameters(param)
01065 , m_agentAddress(m_remoteAddress)
01066 , m_eventPackage(param.m_eventPackage)
01067 , m_eventList(param.m_eventList)
01068 , m_contentType(param.m_contentType)
01069 , m_onSubcribeStatus(param.m_onSubcribeStatus)
01070 , m_onNotify(param.m_onNotify)
01071 { }
01072
01073 PCaselessString & m_agentAddress;
01074 EventPackage m_eventPackage;
01075 bool m_eventList;
01076 PCaselessString m_contentType;
01077
01078 PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
01079 PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
01080 };
01081
01082 SIPSubscribe(
01083 SIPEndPoint & ep,
01084 OpalTransport & trans,
01085 SIPDialogContext & dialog,
01086 const Params & params
01087 );
01088 };
01089
01090
01091 #if PTRACING
01092 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
01093 #endif
01094
01095
01096 typedef SIPSubscribe::EventPackage SIPEventPackage;
01097
01098
01100
01101 class SIPHandler;
01102
01103 class SIPEventPackageHandler
01104 {
01105 public:
01106 virtual ~SIPEventPackageHandler() { }
01107 virtual PCaselessString GetContentType() const = 0;
01108 virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
01109 virtual PString OnSendNOTIFY(SIPHandler & , const PObject * ) { return PString::Empty(); }
01110 };
01111
01112
01113 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01114
01115
01117
01118 class SIPNotify : public SIPTransaction
01119 {
01120 PCLASSINFO(SIPNotify, SIPTransaction);
01121 public:
01122 SIPNotify(
01123 SIPEndPoint & ep,
01124 OpalTransport & trans,
01125 SIPDialogContext & dialog,
01126 const SIPEventPackage & eventPackage,
01127 const PString & state,
01128 const PString & body
01129 );
01130 };
01131
01132
01134
01135 class SIPPublish : public SIPTransaction
01136 {
01137 PCLASSINFO(SIPPublish, SIPTransaction);
01138 public:
01139 SIPPublish(
01140 SIPEndPoint & ep,
01141 OpalTransport & trans,
01142 const PString & id,
01143 const PString & sipIfMatch,
01144 const SIPSubscribe::Params & params,
01145 const PString & body
01146 );
01147 };
01148
01149
01151
01152 class SIPRefer : public SIPTransaction
01153 {
01154 PCLASSINFO(SIPRefer, SIPTransaction);
01155 public:
01156 SIPRefer(
01157 SIPConnection & connection,
01158 const SIPURL & referTo,
01159 const SIPURL & referred_by = SIPURL()
01160 );
01161 };
01162
01163
01165
01166
01167
01168
01169 class SIPReferNotify : public SIPTransaction
01170 {
01171 PCLASSINFO(SIPReferNotify, SIPTransaction);
01172 public:
01173 SIPReferNotify(
01174 SIPConnection & connection,
01175 StatusCodes code
01176 );
01177 };
01178
01179
01181
01182
01183
01184 class SIPMessage : public SIPTransaction
01185 {
01186 PCLASSINFO(SIPMessage, SIPTransaction);
01187 public:
01188 struct Params : public SIPParameters
01189 {
01190 Params()
01191 {
01192 m_expire = 5000;
01193 }
01194
01195 Params(const Params & param)
01196 : SIPParameters(param)
01197 , m_contentType(param.m_contentType)
01198 , m_id(param.m_id)
01199 { }
01200
01201 PCaselessString m_contentType;
01202 PString m_id;
01203 };
01204
01205
01206 public:
01207 SIPMessage(
01208 SIPEndPoint & ep,
01209 OpalTransport & trans,
01210 const Params & params,
01211 const PString & body
01212 );
01213 SIPURL m_localAddress;
01214 };
01215
01216
01218
01219
01220
01221
01222 class SIPAck : public SIP_PDU
01223 {
01224 PCLASSINFO(SIPAck, SIP_PDU);
01225 public:
01226 SIPAck(
01227 SIPTransaction & invite,
01228 SIP_PDU & response
01229 );
01230 };
01231
01232
01234
01235
01236
01237 class SIPOptions : public SIPTransaction
01238 {
01239 PCLASSINFO(SIPOptions, SIPTransaction);
01240
01241 public:
01242 SIPOptions(
01243 SIPEndPoint & ep,
01244 OpalTransport & trans,
01245 const SIPURL & address
01246 );
01247 };
01248
01249
01251
01252
01253
01254 class SIPPing : public SIPTransaction
01255 {
01256 PCLASSINFO(SIPPing, SIPTransaction);
01257
01258 public:
01259 SIPPing(
01260 SIPEndPoint & ep,
01261 OpalTransport & trans,
01262 const SIPURL & address,
01263 const PString & body = PString::Empty()
01264 );
01265 };
01266
01267
01268 #endif // OPAL_SIP
01269
01270 #endif // OPAL_SIP_SIPPDU_H
01271
01272
01273