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