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