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 class SIPMIMEInfo;
00060
00061
00063
00064
00070 class SIPURL : public PURL
00071 {
00072 PCLASSINFO(SIPURL, PURL);
00073 public:
00074 SIPURL();
00075
00076 SIPURL(
00077 const PURL & url
00078 ) : PURL(url) { }
00079 SIPURL & operator=(
00080 const PURL & url
00081 ) { PURL::operator=(url); return *this; }
00082
00085 SIPURL(
00086 const char * cstr,
00087 const char * defaultScheme = NULL
00088 );
00089 SIPURL & operator=(
00090 const char * cstr
00091 ) { Parse(cstr); return *this; }
00092
00095 SIPURL(
00096 const PString & str,
00097 const char * defaultScheme = NULL
00098 );
00099 SIPURL & operator=(
00100 const PString & str
00101 ) { Parse(str); return *this; }
00102
00112 SIPURL(
00113 const PString & name,
00114 const OpalTransportAddress & address,
00115 WORD listenerPort = 0
00116 );
00117
00118 SIPURL(
00119 const OpalTransportAddress & address,
00120 WORD listenerPort = 0
00121 );
00122 SIPURL & operator=(
00123 const OpalTransportAddress & address
00124 );
00125
00126 SIPURL(
00127 const SIPMIMEInfo & mime,
00128 const char * name
00129 );
00130
00139 virtual Comparison Compare(
00140 const PObject & obj
00141 ) const;
00142
00146 PString AsQuotedString() const;
00147
00150 PString GetDisplayName(PBoolean useDefault = true) const;
00151
00152 void SetDisplayName(const PString & str)
00153 {
00154 m_displayName = str;
00155 }
00156
00158 const PStringOptions & GetFieldParameters() const { return m_fieldParameters; }
00159 PStringOptions & GetFieldParameters() { return m_fieldParameters; }
00160
00163 OpalTransportAddress GetHostAddress() const;
00164
00167 void SetHostAddress(const OpalTransportAddress & addr);
00168
00169 enum UsageContext {
00170 ExternalURI,
00171 RequestURI,
00172 ToURI,
00173 FromURI,
00174 RouteURI,
00175 RedirectURI,
00176 ContactURI,
00177 RegContactURI,
00178 RegisterURI
00179 };
00180
00186 void Sanitise(
00187 UsageContext context
00188 );
00189
00195 PBoolean AdjustToDNS(
00196 PINDEX entry = 0
00197 );
00198
00200 static PString GenerateTag();
00201
00203 void SetTag(
00204 const PString & tag = PString::Empty(),
00205 bool force = false
00206 );
00207
00208 protected:
00209 void ParseAsAddress(const PString & name, const OpalTransportAddress & _address, WORD listenerPort = 0);
00210
00211
00212 virtual PBoolean InternalParse(
00213 const char * cstr,
00214 const char * defaultScheme
00215 ) { return ReallyInternalParse(false, cstr, defaultScheme); }
00216
00217 bool ReallyInternalParse(
00218 bool fromField,
00219 const char * cstr,
00220 const char * defaultScheme
00221 );
00222
00223 PString m_displayName;
00224 PStringOptions m_fieldParameters;
00225 };
00226
00227
00228 class SIPURLList : public std::list<SIPURL>
00229 {
00230 public:
00231 bool FromString(
00232 const PString & str,
00233 SIPURL::UsageContext context = SIPURL::RouteURI,
00234 bool reversed = false
00235 );
00236 PString ToString() const;
00237 };
00238
00239
00240
00242
00243
00274 class SIPMIMEInfo : public PMIMEInfo
00275 {
00276 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00277 public:
00278 SIPMIMEInfo(bool compactForm = false);
00279
00280 virtual void PrintOn(ostream & strm) const;
00281 virtual bool InternalAddMIME(const PString & fieldName, const PString & fieldValue);
00282
00283 void SetCompactForm(bool form) { compactForm = form; }
00284
00285 PCaselessString GetContentType(bool includeParameters = false) const;
00286 void SetContentType(const PString & v);
00287
00288 PCaselessString GetContentEncoding() const;
00289 void SetContentEncoding(const PString & v);
00290
00291 SIPURL GetFrom() const;
00292 void SetFrom(const PString & v);
00293
00294 SIPURL GetPAssertedIdentity() const;
00295 void SetPAssertedIdentity(const PString & v);
00296
00297 SIPURL GetPPreferredIdentity() const;
00298 void SetPPreferredIdentity(const PString & v);
00299
00300 PString GetAccept() const;
00301 void SetAccept(const PString & v);
00302
00303 PString GetAcceptEncoding() const;
00304 void SetAcceptEncoding(const PString & v);
00305
00306 PString GetAcceptLanguage() const;
00307 void SetAcceptLanguage(const PString & v);
00308
00309 PString GetAllow() const;
00310 unsigned GetAllowBitMask() const;
00311 void SetAllow(const PString & v);
00312
00313 PString GetCallID() const;
00314 void SetCallID(const PString & v);
00315
00316 SIPURL GetContact() const;
00317 bool GetContacts(SIPURLList & contacts) const;
00318 void SetContact(const PString & v);
00319
00320 PString GetSubject() const;
00321 void SetSubject(const PString & v);
00322
00323 SIPURL GetTo() const;
00324 void SetTo(const PString & v);
00325
00326 PString GetVia() const;
00327 void SetVia(const PString & v);
00328
00329 bool GetViaList(PStringList & v) const;
00330 void SetViaList(const PStringList & v);
00331
00332 PString GetFirstVia() const;
00333 OpalTransportAddress GetViaReceivedAddress() const;
00334
00335 SIPURL GetReferTo() const;
00336 void SetReferTo(const PString & r);
00337
00338 SIPURL GetReferredBy() const;
00339 void SetReferredBy(const PString & r);
00340
00341 PINDEX GetContentLength() const;
00342 void SetContentLength(PINDEX v);
00343 PBoolean IsContentLengthPresent() const;
00344
00345 PString GetCSeq() const;
00346 void SetCSeq(const PString & v);
00347
00348 PString GetDate() const;
00349 void SetDate(const PString & v);
00350 void SetDate(const PTime & t);
00351 void SetDate(void);
00352
00353 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00354 void SetExpires(unsigned v);
00355
00356 PINDEX GetMaxForwards() const;
00357 void SetMaxForwards(PINDEX v);
00358
00359 PINDEX GetMinExpires() const;
00360 void SetMinExpires(PINDEX v);
00361
00362 PString GetProxyAuthenticate() const;
00363 void SetProxyAuthenticate(const PString & v);
00364
00365 PString GetRoute() const;
00366 bool GetRoute(SIPURLList & proxies) const;
00367 void SetRoute(const PString & v);
00368 void SetRoute(const SIPURLList & proxies);
00369
00370 PString GetRecordRoute() const;
00371 bool GetRecordRoute(SIPURLList & proxies, bool reversed) const;
00372 void SetRecordRoute(const PString & v);
00373 void SetRecordRoute(const SIPURLList & proxies);
00374
00375 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00376
00377 PStringSet GetRequire() const;
00378 void SetRequire(const PStringSet & v);
00379 void AddRequire(const PString & v);
00380
00381 PStringSet GetSupported() const;
00382 void SetSupported(const PStringSet & v);
00383 void AddSupported(const PString & v);
00384
00385 PStringSet GetUnsupported() const;
00386 void SetUnsupported(const PStringSet & v);
00387 void AddUnsupported(const PString & v);
00388
00389 PString GetEvent() const;
00390 void SetEvent(const PString & v);
00391
00392 PCaselessString GetSubscriptionState(PStringToString & info) const;
00393 void SetSubscriptionState(const PString & v);
00394
00395 PString GetUserAgent() const;
00396 void SetUserAgent(const PString & v);
00397
00398 PString GetOrganization() const;
00399 void SetOrganization(const PString & v);
00400
00401 void GetProductInfo(OpalProductInfo & info) const;
00402 void SetProductInfo(const PString & ua, const OpalProductInfo & info);
00403
00404 PString GetWWWAuthenticate() const;
00405 void SetWWWAuthenticate(const PString & v);
00406
00407 PString GetSIPIfMatch() const;
00408 void SetSIPIfMatch(const PString & v);
00409
00410 PString GetSIPETag() const;
00411 void SetSIPETag(const PString & v);
00412
00413 void GetAlertInfo(PString & info, int & appearance);
00414 void SetAlertInfo(const PString & info, int appearance);
00415
00416 PString GetCallInfo() const;
00417
00418 PString GetAllowEvents() const;
00419 void SetAllowEvents(const PString & v);
00420
00423 PString GetFieldParameter(
00424 const PString & fieldName,
00425 const PString & paramName,
00426 const PString & defaultValue = PString::Empty()
00427 ) const { return ExtractFieldParameter((*this)(fieldName), paramName, defaultValue); }
00428
00433 void SetFieldParameter(
00434 const PString & fieldName,
00435 const PString & paramName,
00436 const PString & newValue
00437 ) { SetAt(fieldName, InsertFieldParameter((*this)(fieldName), paramName, newValue)); }
00438
00441 static PString ExtractFieldParameter(
00442 const PString & fieldValue,
00443 const PString & paramName,
00444 const PString & defaultValue = PString::Empty()
00445 );
00446
00451 static PString InsertFieldParameter(
00452 const PString & fieldValue,
00453 const PString & paramName,
00454 const PString & newValue
00455 );
00456
00457 protected:
00458 PStringSet GetTokenSet(const char * field) const;
00459 void AddTokenSet(const char * field, const PString & token);
00460 void SetTokenSet(const char * field, const PStringSet & tokens);
00461
00463 bool compactForm;
00464 };
00465
00466
00468
00469
00470 typedef PHTTPClientAuthentication SIPAuthentication;
00471
00472 class SIPAuthenticator : public PHTTPClientAuthentication::AuthObject
00473 {
00474 public:
00475 SIPAuthenticator(SIP_PDU & pdu);
00476 virtual PMIMEInfo & GetMIME();
00477 virtual PString GetURI();
00478 virtual PString GetEntityBody();
00479 virtual PString GetMethod();
00480
00481 protected:
00482 SIP_PDU & m_pdu;
00483 };
00484
00485
00486
00488
00489
00495 class SIP_PDU : public PSafeObject
00496 {
00497 PCLASSINFO(SIP_PDU, PSafeObject);
00498 public:
00499 enum Methods {
00500 Method_INVITE,
00501 Method_ACK,
00502 Method_OPTIONS,
00503 Method_BYE,
00504 Method_CANCEL,
00505 Method_REGISTER,
00506 Method_SUBSCRIBE,
00507 Method_NOTIFY,
00508 Method_REFER,
00509 Method_MESSAGE,
00510 Method_INFO,
00511 Method_PING,
00512 Method_PUBLISH,
00513 Method_PRACK,
00514 NumMethods
00515 };
00516
00517 enum StatusCodes {
00518 IllegalStatusCode,
00519 Local_TransportError,
00520 Local_BadTransportAddress,
00521 Local_Timeout,
00522
00523 Information_Trying = 100,
00524 Information_Ringing = 180,
00525 Information_CallForwarded = 181,
00526 Information_Queued = 182,
00527 Information_Session_Progress = 183,
00528
00529 Successful_OK = 200,
00530 Successful_Accepted = 202,
00531
00532 Redirection_MultipleChoices = 300,
00533 Redirection_MovedPermanently = 301,
00534 Redirection_MovedTemporarily = 302,
00535 Redirection_UseProxy = 305,
00536 Redirection_AlternativeService = 380,
00537
00538 Failure_BadRequest = 400,
00539 Failure_UnAuthorised = 401,
00540 Failure_PaymentRequired = 402,
00541 Failure_Forbidden = 403,
00542 Failure_NotFound = 404,
00543 Failure_MethodNotAllowed = 405,
00544 Failure_NotAcceptable = 406,
00545 Failure_ProxyAuthenticationRequired = 407,
00546 Failure_RequestTimeout = 408,
00547 Failure_Conflict = 409,
00548 Failure_Gone = 410,
00549 Failure_LengthRequired = 411,
00550 Failure_RequestEntityTooLarge = 413,
00551 Failure_RequestURITooLong = 414,
00552 Failure_UnsupportedMediaType = 415,
00553 Failure_UnsupportedURIScheme = 416,
00554 Failure_BadExtension = 420,
00555 Failure_ExtensionRequired = 421,
00556 Failure_IntervalTooBrief = 423,
00557 Failure_TemporarilyUnavailable = 480,
00558 Failure_TransactionDoesNotExist = 481,
00559 Failure_LoopDetected = 482,
00560 Failure_TooManyHops = 483,
00561 Failure_AddressIncomplete = 484,
00562 Failure_Ambiguous = 485,
00563 Failure_BusyHere = 486,
00564 Failure_RequestTerminated = 487,
00565 Failure_NotAcceptableHere = 488,
00566 Failure_BadEvent = 489,
00567 Failure_RequestPending = 491,
00568 Failure_Undecipherable = 493,
00569
00570 Failure_InternalServerError = 500,
00571 Failure_NotImplemented = 501,
00572 Failure_BadGateway = 502,
00573 Failure_ServiceUnavailable = 503,
00574 Failure_ServerTimeout = 504,
00575 Failure_SIPVersionNotSupported = 505,
00576 Failure_MessageTooLarge = 513,
00577
00578 GlobalFailure_BusyEverywhere = 600,
00579 GlobalFailure_Decline = 603,
00580 GlobalFailure_DoesNotExistAnywhere = 604,
00581 GlobalFailure_NotAcceptable = 606,
00582
00583 MaxStatusCode = 699
00584 };
00585
00586 static const char * GetStatusCodeDescription(int code);
00587 friend ostream & operator<<(ostream & strm, StatusCodes status);
00588
00589 SIP_PDU(
00590 Methods method = SIP_PDU::NumMethods
00591 );
00592
00596 SIP_PDU(
00597 const SIP_PDU & request,
00598 StatusCodes code,
00599 const SDPSessionDescription * sdp = NULL
00600 );
00601
00602 SIP_PDU(const SIP_PDU &);
00603 SIP_PDU & operator=(const SIP_PDU &);
00604 ~SIP_PDU();
00605
00606 void PrintOn(
00607 ostream & strm
00608 ) const;
00609
00610 void InitialiseHeaders(
00611 const SIPURL & dest,
00612 const SIPURL & to,
00613 const SIPURL & from,
00614 const PString & callID,
00615 unsigned cseq,
00616 const PString & via
00617 );
00618 void InitialiseHeaders(
00619 SIPDialogContext & dialog,
00620 const PString & via = PString::Empty(),
00621 unsigned cseq = 0
00622 );
00623 void InitialiseHeaders(
00624 SIPConnection & connection,
00625 const OpalTransport & transport,
00626 unsigned cseq = 0
00627 );
00628 void InitialiseHeaders(
00629 const SIP_PDU & request
00630 );
00631
00636 bool SetRoute(const SIPURLList & routeSet);
00637 bool SetRoute(const SIPURL & proxy);
00638
00641 void SetAllow(unsigned bitmask);
00642
00645 void AdjustVia(OpalTransport & transport);
00646
00647 PString CreateVia(
00648 SIPEndPoint & endpoint,
00649 const OpalTransport & transport,
00650 SIPConnection * connection = NULL
00651 );
00652
00655 SIP_PDU::StatusCodes Read(
00656 OpalTransport & transport
00657 );
00658
00661 PBoolean Write(
00662 OpalTransport & transport,
00663 const OpalTransportAddress & remoteAddress = OpalTransportAddress(),
00664 const PString & localInterface = PString::Empty()
00665 );
00666
00669 bool SendResponse(
00670 OpalTransport & transport,
00671 StatusCodes code,
00672 SIPEndPoint * endpoint = NULL
00673 ) const;
00674 bool SendResponse(
00675 OpalTransport & transport,
00676 SIP_PDU & response,
00677 SIPEndPoint * endpoint = NULL
00678 ) const;
00679
00683 PString Build();
00684
00685 PString GetTransactionID() const;
00686
00687 Methods GetMethod() const { return m_method; }
00688 StatusCodes GetStatusCode () const { return m_statusCode; }
00689 void SetStatusCode (StatusCodes c) { m_statusCode = c; }
00690 const SIPURL & GetURI() const { return m_uri; }
00691 void SetURI(const SIPURL & newuri) { m_uri = newuri; }
00692 unsigned GetVersionMajor() const { return m_versionMajor; }
00693 unsigned GetVersionMinor() const { return m_versionMinor; }
00694 void SetCSeq(unsigned cseq);
00695 const PString & GetEntityBody() const { return m_entityBody; }
00696 void SetEntityBody(const PString & body) { m_entityBody = body; }
00697 void SetEntityBody();
00698 const PString & GetInfo() const { return m_info; }
00699 void SetInfo(const PString & info) { m_info = info; }
00700 const SIPMIMEInfo & GetMIME() const { return m_mime; }
00701 SIPMIMEInfo & GetMIME() { return m_mime; }
00702 SDPSessionDescription * GetSDP(const OpalMediaFormatList & masterList);
00703 void SetSDP(SDPSessionDescription * sdp);
00704
00705 protected:
00706 Methods m_method;
00707 StatusCodes m_statusCode;
00708 SIPURL m_uri;
00709 unsigned m_versionMajor;
00710 unsigned m_versionMinor;
00711 PString m_info;
00712 SIPMIMEInfo m_mime;
00713 PString m_entityBody;
00714
00715 SDPSessionDescription * m_SDP;
00716
00717 mutable PString m_transactionID;
00718 };
00719
00720
00721 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00722
00723
00724 #if PTRACING
00725 ostream & operator<<(ostream & strm, SIP_PDU::Methods method);
00726 #endif
00727
00728
00730
00731
00734 class SIPDialogContext
00735 {
00736 public:
00737 SIPDialogContext();
00738 SIPDialogContext(const SIPMIMEInfo & mime);
00739
00740 PString AsString() const;
00741 bool FromString(
00742 const PString & str
00743 );
00744
00745 const PString & GetCallID() const { return m_callId; }
00746 void SetCallID(const PString & id) { m_callId = id; }
00747
00748 const SIPURL & GetRequestURI() const { return m_requestURI; }
00749 void SetRequestURI(const SIPURL & url) { m_requestURI = url; }
00750
00751 const PString & GetLocalTag() const { return m_localTag; }
00752 void SetLocalTag(const PString & tag) { m_localTag = tag; }
00753
00754 const SIPURL & GetLocalURI() const { return m_localURI; }
00755 void SetLocalURI(const SIPURL & url);
00756
00757 const PString & GetRemoteTag() const { return m_remoteTag; }
00758 void SetRemoteTag(const PString & tag) { m_remoteTag = tag; }
00759
00760 const SIPURL & GetRemoteURI() const { return m_remoteURI; }
00761 void SetRemoteURI(const SIPURL & url);
00762
00763 const SIPURLList & GetRouteSet() const { return m_routeSet; }
00764 void SetRouteSet(const PString & str) { m_routeSet.FromString(str); }
00765
00766 const SIPURL & GetProxy() const { return m_proxy; }
00767 void SetProxy(const SIPURL & proxy, bool addToRouteSet);
00768
00769 void Update(OpalTransport & transport, const SIP_PDU & response);
00770
00771 unsigned GetNextCSeq();
00772 void IncrementCSeq(unsigned inc) { m_lastSentCSeq += inc; }
00773
00774 bool IsDuplicateCSeq(unsigned sequenceNumber);
00775
00776 bool IsEstablished() const
00777 {
00778 return !m_callId.IsEmpty() &&
00779 !m_requestURI.IsEmpty() &&
00780 !m_localTag.IsEmpty() &&
00781 !m_remoteTag.IsEmpty();
00782 }
00783
00784 OpalTransportAddress GetRemoteTransportAddress() const;
00785
00786 void SetForking(bool f) { m_forking = f; }
00787
00788 protected:
00789 PString m_callId;
00790 SIPURL m_requestURI;
00791 SIPURL m_localURI;
00792 PString m_localTag;
00793 SIPURL m_remoteURI;
00794 PString m_remoteTag;
00795 SIPURLList m_routeSet;
00796 unsigned m_lastSentCSeq;
00797 unsigned m_lastReceivedCSeq;
00798 OpalTransportAddress m_externalTransportAddress;
00799 bool m_forking;
00800 SIPURL m_proxy;
00801 };
00802
00803
00805
00806 struct SIPParameters
00807 {
00808 SIPParameters(
00809 const PString & aor = PString::Empty(),
00810 const PString & remote = PString::Empty()
00811 );
00812
00813 void Normalise(
00814 const PString & defaultUser,
00815 const PTimeInterval & defaultExpire
00816 );
00817
00818 PCaselessString m_remoteAddress;
00819 PCaselessString m_localAddress;
00820 PCaselessString m_proxyAddress;
00821 PCaselessString m_addressOfRecord;
00822 PCaselessString m_contactAddress;
00823 SIPMIMEInfo m_mime;
00824 PString m_authID;
00825 PString m_password;
00826 PString m_realm;
00827 unsigned m_expire;
00828 unsigned m_restoreTime;
00829 PTimeInterval m_minRetryTime;
00830 PTimeInterval m_maxRetryTime;
00831 void * m_userData;
00832 };
00833
00834
00835 #if PTRACING
00836 ostream & operator<<(ostream & strm, const SIPParameters & params);
00837 #endif
00838
00839
00841
00842
00853 class SIPTransaction : public SIP_PDU
00854 {
00855 PCLASSINFO(SIPTransaction, SIP_PDU);
00856 public:
00857 SIPTransaction(
00858 Methods method,
00859 SIPEndPoint & endpoint,
00860 OpalTransport & transport
00861 );
00865 SIPTransaction(
00866 Methods method,
00867 SIPConnection & connection
00868 );
00869 ~SIPTransaction();
00870
00871
00872
00873 virtual SIPTransaction * CreateDuplicate() const = 0;
00874
00875 PBoolean Start();
00876 bool IsTrying() const { return m_state == Trying; }
00877 bool IsProceeding() const { return m_state == Proceeding; }
00878 bool IsInProgress() const { return m_state == Trying || m_state == Proceeding; }
00879 bool IsFailed() const { return m_state > Terminated_Success; }
00880 bool IsCompleted() const { return m_state >= Completed; }
00881 bool IsCanceled() const { return m_state == Cancelling || m_state == Terminated_Cancelled || m_state == Terminated_Aborted; }
00882 bool IsTerminated() const { return m_state >= Terminated_Success; }
00883
00884 void WaitForCompletion();
00885 PBoolean Cancel();
00886 void Abort();
00887
00888 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00889 virtual PBoolean OnCompleted(SIP_PDU & response);
00890
00891 OpalTransport & GetTransport() const { return m_transport; }
00892 SIPConnection * GetConnection() const { return m_connection; }
00893 PString GetInterface() const { return m_localInterface; }
00894 void SetInterface(const PString & localIf) { m_localInterface = localIf; }
00895
00896 static PString GenerateCallID();
00897
00898 protected:
00899 bool SendPDU(SIP_PDU & pdu);
00900 bool ResendCANCEL();
00901 void SetParameters(const SIPParameters & params);
00902
00903 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00904 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00905
00906 enum States {
00907 NotStarted,
00908 Trying,
00909 Proceeding,
00910 Cancelling,
00911 Completed,
00912 Terminated_Success,
00913 Terminated_Timeout,
00914 Terminated_RetriesExceeded,
00915 Terminated_TransportError,
00916 Terminated_Cancelled,
00917 Terminated_Aborted,
00918 NumStates
00919 };
00920 virtual void SetTerminated(States newState);
00921
00922 SIPEndPoint & m_endpoint;
00923 OpalTransport & m_transport;
00924 PSafePtr<SIPConnection> m_connection;
00925 PTimeInterval m_retryTimeoutMin;
00926 PTimeInterval m_retryTimeoutMax;
00927
00928 States m_state;
00929 unsigned m_retry;
00930 PTimer m_retryTimer;
00931 PTimer m_completionTimer;
00932 PSyncPoint m_completed;
00933
00934 PString m_localInterface;
00935 OpalTransportAddress m_remoteAddress;
00936 };
00937
00938
00939 #define OPAL_PROXY_PARAM "OPAL-proxy"
00940 #define OPAL_LOCAL_ID_PARAM "OPAL-local-id"
00941
00942
00944
00945
00948 class SIPResponse : public SIPTransaction
00949 {
00950 PCLASSINFO(SIPResponse, SIPTransaction);
00951 public:
00952 SIPResponse(
00953 SIPEndPoint & endpoint,
00954 StatusCodes code
00955 );
00956
00957 virtual SIPTransaction * CreateDuplicate() const;
00958
00959 bool Send(OpalTransport & transport, const SIP_PDU & command);
00960 };
00961
00962
00964
00965
00971 class SIPInvite : public SIPTransaction
00972 {
00973 PCLASSINFO(SIPInvite, SIPTransaction);
00974 public:
00975 SIPInvite(
00976 SIPConnection & connection,
00977 const OpalRTPSessionManager & sm
00978 );
00979
00980 virtual SIPTransaction * CreateDuplicate() const;
00981
00982 virtual PBoolean OnReceivedResponse(SIP_PDU & response);
00983
00984 const OpalRTPSessionManager & GetSessionManager() const { return m_rtpSessions; }
00985 OpalRTPSessionManager & GetSessionManager() { return m_rtpSessions; }
00986
00987 protected:
00988 OpalRTPSessionManager m_rtpSessions;
00989 };
00990
00991
00993
00994
00995
00996
00997 class SIPAck : public SIP_PDU
00998 {
00999 PCLASSINFO(SIPAck, SIP_PDU);
01000 public:
01001 SIPAck(
01002 SIPTransaction & invite,
01003 SIP_PDU & response
01004 );
01005
01006 virtual SIPTransaction * CreateDuplicate() const;
01007 };
01008
01009
01011
01012
01013
01014 class SIPBye : public SIPTransaction
01015 {
01016 PCLASSINFO(SIPBye, SIPTransaction);
01017
01018 public:
01019 SIPBye(
01020 SIPEndPoint & ep,
01021 OpalTransport & trans,
01022 SIPDialogContext dialog
01023 );
01024 SIPBye(
01025 SIPConnection & conn
01026 );
01027
01028 virtual SIPTransaction * CreateDuplicate() const;
01029 };
01030
01031
01033
01034 class SIPRegister : public SIPTransaction
01035 {
01036 PCLASSINFO(SIPRegister, SIPTransaction);
01037 public:
01038 enum CompatibilityModes {
01039 e_FullyCompliant,
01042 e_CannotRegisterMultipleContacts,
01046 e_CannotRegisterPrivateContacts,
01050 e_HasApplicationLayerGateway
01054 };
01055
01057 struct Params : public SIPParameters {
01058 Params()
01059 : m_registrarAddress(m_remoteAddress)
01060 , m_compatibility(SIPRegister::e_FullyCompliant)
01061 { }
01062
01063 Params(const Params & param)
01064 : SIPParameters(param)
01065 , m_registrarAddress(m_remoteAddress)
01066 , m_compatibility(param.m_compatibility)
01067 { }
01068
01069 PCaselessString & m_registrarAddress;
01070 CompatibilityModes m_compatibility;
01071 };
01072
01073 SIPRegister(
01074 SIPEndPoint & endpoint,
01075 OpalTransport & transport,
01076 const PString & callId,
01077 unsigned cseq,
01078 const Params & params
01079 );
01080
01081 virtual SIPTransaction * CreateDuplicate() const;
01082 };
01083
01084
01085 #if PTRACING
01086 ostream & operator<<(ostream & strm, SIPRegister::CompatibilityModes mode);
01087 ostream & operator<<(ostream & strm, const SIPRegister::Params & params);
01088 #endif
01089
01090
01092
01093 class SIPSubscribe : public SIPTransaction
01094 {
01095 PCLASSINFO(SIPSubscribe, SIPTransaction);
01096 public:
01099 enum PredefinedPackages {
01100 MessageSummary,
01101 Presence,
01102 Dialog,
01103
01104 NumPredefinedPackages,
01105
01106 Watcher = 0x8000,
01107
01108 MessageSummaryWatcher = Watcher|MessageSummary,
01109 PresenceWatcher = Watcher|Presence,
01110 DialogWatcher = Watcher|Dialog,
01111
01112 PackageMask = Watcher-1
01113 };
01114 friend PredefinedPackages operator|(PredefinedPackages p1, PredefinedPackages p2) { return (PredefinedPackages)((int)p1|(int)p2); }
01115
01116 class EventPackage : public PCaselessString
01117 {
01118 PCLASSINFO(EventPackage, PCaselessString);
01119 public:
01120 EventPackage(PredefinedPackages = NumPredefinedPackages);
01121 explicit EventPackage(const PString & str) : PCaselessString(str) { }
01122 explicit EventPackage(const char * str) : PCaselessString(str) { }
01123
01124 EventPackage & operator=(PredefinedPackages pkg);
01125 EventPackage & operator=(const PString & str) { PCaselessString::operator=(str); return *this; }
01126 EventPackage & operator=(const char * str) { PCaselessString::operator=(str); return *this; }
01127
01128 bool operator==(PredefinedPackages pkg) const { return Compare(EventPackage(pkg)) == EqualTo; }
01129 bool operator==(const PString & str) const { return Compare(str) == EqualTo; }
01130 bool operator==(const char * cstr) const { return InternalCompare(0, P_MAX_INDEX, cstr) == EqualTo; }
01131 virtual Comparison InternalCompare(PINDEX offset, PINDEX length, const char * cstr) const;
01132
01133 bool IsWatcher() const;
01134 };
01135
01137 struct SubscriptionStatus {
01138 SIPSubscribeHandler * m_handler;
01139 PString m_addressofRecord;
01140 bool m_wasSubscribing;
01141 bool m_reSubscribing;
01142 SIP_PDU::StatusCodes m_reason;
01143 OpalProductInfo m_productInfo;
01144 void * m_userData;
01145 };
01146
01147 struct NotifyCallbackInfo {
01148 NotifyCallbackInfo(
01149 SIPEndPoint & ep,
01150 OpalTransport & trans,
01151 SIP_PDU & notify,
01152 SIP_PDU & response
01153 );
01154
01155 bool SendResponse(
01156 SIP_PDU::StatusCodes status,
01157 const char * extra = NULL
01158 );
01159
01160 SIPEndPoint & m_endpoint;
01161 OpalTransport & m_transport;
01162 SIP_PDU & m_notify;
01163 SIP_PDU & m_response;
01164 bool m_sendResponse;
01165 };
01166
01167 struct Params : public SIPParameters
01168 {
01169 Params(PredefinedPackages pkg = NumPredefinedPackages)
01170 : m_agentAddress(m_remoteAddress)
01171 , m_eventPackage(pkg)
01172 , m_eventList(false)
01173 { }
01174
01175 Params(const Params & param)
01176 : SIPParameters(param)
01177 , m_agentAddress(m_remoteAddress)
01178 , m_eventPackage(param.m_eventPackage)
01179 , m_eventList(param.m_eventList)
01180 , m_contentType(param.m_contentType)
01181 , m_onSubcribeStatus(param.m_onSubcribeStatus)
01182 , m_onNotify(param.m_onNotify)
01183 { }
01184
01185 PCaselessString & m_agentAddress;
01186 EventPackage m_eventPackage;
01187 bool m_eventList;
01188 PCaselessString m_contentType;
01189
01190 PNotifierTemplate<const SubscriptionStatus &> m_onSubcribeStatus;
01191 PNotifierTemplate<NotifyCallbackInfo &> m_onNotify;
01192 };
01193
01194 SIPSubscribe(
01195 SIPEndPoint & ep,
01196 OpalTransport & trans,
01197 SIPDialogContext & dialog,
01198 const Params & params
01199 );
01200
01201 virtual SIPTransaction * CreateDuplicate() const;
01202 };
01203
01204
01205 #if PTRACING
01206 ostream & operator<<(ostream & strm, const SIPSubscribe::Params & params);
01207 #endif
01208
01209
01210 typedef SIPSubscribe::EventPackage SIPEventPackage;
01211
01212
01214
01215 class SIPHandler;
01216
01217 class SIPEventPackageHandler
01218 {
01219 public:
01220 virtual ~SIPEventPackageHandler() { }
01221 virtual PCaselessString GetContentType() const = 0;
01222 virtual bool ValidateContentType(const PString & type, const SIPMIMEInfo & mime);
01223 virtual bool OnReceivedNOTIFY(SIPHandler & handler, SIP_PDU & request) = 0;
01224 virtual PString OnSendNOTIFY(SIPHandler & , const PObject * ) { return PString::Empty(); }
01225 };
01226
01227
01228 typedef PFactory<SIPEventPackageHandler, SIPEventPackage> SIPEventPackageFactory;
01229
01230
01232
01233 class SIPNotify : public SIPTransaction
01234 {
01235 PCLASSINFO(SIPNotify, SIPTransaction);
01236 public:
01237 SIPNotify(
01238 SIPEndPoint & ep,
01239 OpalTransport & trans,
01240 SIPDialogContext & dialog,
01241 const SIPEventPackage & eventPackage,
01242 const PString & state,
01243 const PString & body
01244 );
01245
01246 virtual SIPTransaction * CreateDuplicate() const;
01247 };
01248
01249
01251
01252 class SIPPublish : public SIPTransaction
01253 {
01254 PCLASSINFO(SIPPublish, SIPTransaction);
01255 public:
01256 SIPPublish(
01257 SIPEndPoint & ep,
01258 OpalTransport & trans,
01259 const PString & id,
01260 const PString & sipIfMatch,
01261 const SIPSubscribe::Params & params,
01262 const PString & body
01263 );
01264
01265 virtual SIPTransaction * CreateDuplicate() const;
01266 };
01267
01268
01270
01271 class SIPRefer : public SIPTransaction
01272 {
01273 PCLASSINFO(SIPRefer, SIPTransaction);
01274 public:
01275 SIPRefer(
01276 SIPConnection & connection,
01277 const SIPURL & referTo,
01278 const SIPURL & referred_by,
01279 bool referSub
01280 );
01281
01282 virtual SIPTransaction * CreateDuplicate() const;
01283 };
01284
01285
01287
01288
01289
01290
01291 class SIPReferNotify : public SIPTransaction
01292 {
01293 PCLASSINFO(SIPReferNotify, SIPTransaction);
01294 public:
01295 SIPReferNotify(
01296 SIPConnection & connection,
01297 StatusCodes code
01298 );
01299
01300 virtual SIPTransaction * CreateDuplicate() const;
01301 };
01302
01303
01305
01306
01307
01308 class SIPMessage : public SIPTransaction
01309 {
01310 PCLASSINFO(SIPMessage, SIPTransaction);
01311 public:
01312 struct Params : public SIPParameters
01313 {
01314 Params()
01315 : m_contentType("text/plain;charset=UTF-8")
01316 {
01317 m_expire = 5000;
01318 }
01319
01320 PCaselessString m_contentType;
01321 PString m_id;
01322 PString m_body;
01323 PAtomicInteger::IntegerType m_messageId;
01324 };
01325
01326 SIPMessage(
01327 SIPEndPoint & ep,
01328 OpalTransport & trans,
01329 const Params & params
01330 );
01331 SIPMessage(
01332 SIPConnection & connection,
01333 const Params & params
01334 );
01335
01336 virtual SIPTransaction * CreateDuplicate() const;
01337
01338 const SIPURL & GetLocalAddress() const { return m_localAddress; }
01339
01340 private:
01341 void Construct(const Params & params);
01342
01343 SIPURL m_localAddress;
01344 };
01345
01346
01348
01349
01350
01351 class SIPOptions : public SIPTransaction
01352 {
01353 PCLASSINFO(SIPOptions, SIPTransaction);
01354
01355 public:
01356 struct Params : public SIPParameters
01357 {
01358 Params()
01359 : m_acceptContent("application/sdp, application/media_control+xml, application/dtmf, application/dtmf-relay")
01360 {
01361 }
01362
01363 PCaselessString m_acceptContent;
01364 PCaselessString m_contentType;
01365 PString m_body;
01366 };
01367
01368 SIPOptions(
01369 SIPEndPoint & ep,
01370 OpalTransport & trans,
01371 const PString & id,
01372 const Params & params
01373 );
01374 SIPOptions(
01375 SIPConnection & conn,
01376 const Params & params
01377 );
01378
01379 virtual SIPTransaction * CreateDuplicate() const;
01380
01381 protected:
01382 void Construct(const Params & params);
01383 };
01384
01385
01387
01388
01389
01390 class SIPInfo : public SIPTransaction
01391 {
01392 PCLASSINFO(SIPInfo, SIPTransaction);
01393
01394 public:
01395 struct Params
01396 {
01397 Params(const PString & contentType = PString::Empty(),
01398 const PString & body = PString::Empty())
01399 : m_contentType(contentType)
01400 , m_body(body)
01401 {
01402 }
01403
01404 PCaselessString m_contentType;
01405 PString m_body;
01406 };
01407
01408 SIPInfo(
01409 SIPConnection & conn,
01410 const Params & params
01411 );
01412
01413 virtual SIPTransaction * CreateDuplicate() const;
01414 };
01415
01416
01418
01419
01420
01421 class SIPPing : public SIPTransaction
01422 {
01423 PCLASSINFO(SIPPing, SIPTransaction);
01424
01425 public:
01426 SIPPing(
01427 SIPEndPoint & ep,
01428 OpalTransport & trans,
01429 const SIPURL & address
01430 );
01431
01432 virtual SIPTransaction * CreateDuplicate() const;
01433 };
01434
01435
01437
01438
01439
01440 class SIPPrack : public SIPTransaction
01441 {
01442 PCLASSINFO(SIPPrack, SIPTransaction);
01443
01444 public:
01445 SIPPrack(
01446 SIPConnection & conn,
01447 const PString & rack
01448 );
01449
01450 virtual SIPTransaction * CreateDuplicate() const;
01451 };
01452
01453
01454 #endif // OPAL_SIP
01455
01456 #endif // OPAL_SIP_SIPPDU_H
01457
01458
01459