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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 #ifndef __OPAL_SIPPDU_H
00154 #define __OPAL_SIPPDU_H
00155
00156 #ifdef P_USE_PRAGMA
00157 #pragma interface
00158 #endif
00159
00160
00161 #include <ptclib/mime.h>
00162 #include <ptclib/url.h>
00163 #include <sip/sdp.h>
00164
00165
00166 class OpalTransport;
00167 class OpalTransportAddress;
00168
00169 class SIPEndPoint;
00170 class SIPConnection;
00171 class SIP_PDU;
00172
00173
00175
00176
00182 class SIPURL : public PURL
00183 {
00184 PCLASSINFO(SIPURL, PURL);
00185 public:
00186 SIPURL();
00187
00190 SIPURL(
00191 const char * cstr,
00192 const char * defaultScheme = NULL
00193 );
00194
00197 SIPURL(
00198 const PString & str,
00199 const char * defaultScheme = NULL
00200 );
00201
00209 SIPURL(
00210 const PString & name,
00211 const OpalTransportAddress & address,
00212 WORD listenerPort = 0
00213 );
00214
00218 PString AsQuotedString() const;
00219
00222 PString GetDisplayName() const;
00223
00224 void SetDisplayName(const PString & str)
00225 { displayName = str; }
00226
00227 OpalTransportAddress GetHostAddress() const;
00228
00232 void AdjustForRequestURI();
00233
00234 protected:
00253 virtual BOOL InternalParse(
00254 const char * cstr,
00255 const char * defaultScheme
00256 );
00257
00258 PString displayName;
00259 };
00260
00261
00263
00264
00295 class SIPMIMEInfo : public PMIMEInfo
00296 {
00297 PCLASSINFO(SIPMIMEInfo, PMIMEInfo);
00298 public:
00299 SIPMIMEInfo(BOOL compactForm = FALSE);
00300
00301 void SetForm(BOOL v) { compactForm = v; }
00302
00303 PString GetContentType() const;
00304 void SetContentType(const PString & v);
00305
00306 PString GetContentEncoding() const;
00307 void SetContentEncoding(const PString & v);
00308
00309 PString GetFrom() const;
00310 void SetFrom(const PString & v);
00311
00312 PString GetAccept() const;
00313 void SetAccept(const PString & v);
00314
00315 PString GetAcceptEncoding() const;
00316 void SetAcceptEncoding(const PString & v);
00317
00318 PString GetAcceptLanguage() const;
00319 void SetAcceptLanguage(const PString & v);
00320
00321 PString GetAllow() const;
00322 void SetAllow(const PString & v);
00323
00324 PString GetCallID() const;
00325 void SetCallID(const PString & v);
00326
00327 PString GetContact() const;
00328 void SetContact(const PString & v);
00329 void SetContact(const SIPURL & url);
00330
00331 PString GetSubject() const;
00332 void SetSubject(const PString & v);
00333
00334 PString GetTo() const;
00335 void SetTo(const PString & v);
00336
00337 PString GetVia() const;
00338 void SetVia(const PString & v);
00339
00340 PStringList GetViaList() const;
00341 void SetViaList(const PStringList & v);
00342
00343 PString GetReferTo() const;
00344 void SetReferTo(const PString & r);
00345
00346 PINDEX GetContentLength() const;
00347 void SetContentLength(PINDEX v);
00348
00349 PString GetCSeq() const;
00350 void SetCSeq(const PString & v);
00351
00352 PString GetDate() const;
00353 void SetDate(const PString & v);
00354 void SetDate(const PTime & t);
00355 void SetDate(void);
00356
00357 unsigned GetExpires(unsigned dflt = UINT_MAX) const;
00358 void SetExpires(unsigned v);
00359
00360 PINDEX GetMaxForwards() const;
00361 void SetMaxForwards(PINDEX v);
00362
00363 PINDEX GetMinExpires() const;
00364 void SetMinExpires(PINDEX v);
00365
00366 PString GetProxyAuthenticate() const;
00367 void SetProxyAuthenticate(const PString & v);
00368
00369 PStringList GetRoute() const;
00370 void SetRoute(const PStringList & v);
00371
00372 PStringList GetRecordRoute() const;
00373 void SetRecordRoute(const PStringList & v);
00374
00375 unsigned GetCSeqIndex() const { return GetCSeq().AsUnsigned(); }
00376
00377 PString GetSupported() const;
00378 void SetSupported(const PString & v);
00379
00380 PString GetUnsupported() const;
00381 void SetUnsupported(const PString & v);
00382
00383 PString GetEvent() const;
00384 void SetEvent(const PString & v);
00385
00386 PString GetSubscriptionState() const;
00387 void SetSubscriptionState(const PString & v);
00388
00389 PString GetUserAgent() const;
00390 void SetUserAgent(const SIPEndPoint & sipep);
00391
00392 PString GetWWWAuthenticate() const;
00393 void SetWWWAuthenticate(const PString & v);
00394
00395
00398 PString GetFieldParameter(const PString &,
00399 const PString &);
00400
00405 void SetFieldParameter(const PString &,
00406 PString &,
00407 const PString &);
00408
00411 BOOL HasFieldParameter(const PString &,
00412 const PString &);
00413
00414 protected:
00417 PStringList GetRouteList(const char * name) const;
00418
00422 void SetRouteList(const char * name, const PStringList & v);
00423
00426 PString GetFullOrCompact(const char * fullForm, char compactForm) const;
00427
00429 BOOL compactForm;
00430 };
00431
00432
00434
00435
00436 class SIPAuthentication : public PObject
00437 {
00438 PCLASSINFO(SIPAuthentication, PObject);
00439 public:
00440 SIPAuthentication(
00441 const PString & username = PString::Empty(),
00442 const PString & password = PString::Empty()
00443 );
00444
00445 BOOL Parse(
00446 const PCaselessString & auth,
00447 BOOL proxy
00448 );
00449
00450 BOOL IsValid() const;
00451
00452 BOOL Authorise(
00453 SIP_PDU & pdu
00454 ) const;
00455
00456 enum Algorithm {
00457 Algorithm_MD5,
00458 NumAlgorithms
00459 };
00460
00461 BOOL IsProxy() const { return isProxy; }
00462 const PString & GetAuthRealm() const { return authRealm; }
00463 const PString & GetUsername() const { return username; }
00464 const PString & GetPassword() const { return password; }
00465 const PString & GetNonce() const { return nonce; }
00466 Algorithm GetAlgorithm() const { return algorithm; }
00467
00468 void SetUsername(const PString & user) { username = user; }
00469 void SetPassword(const PString & pass) { password = pass; }
00470 void SetAuthRealm(const PString & r) { authRealm = r; }
00471
00472 protected:
00473 BOOL isProxy;
00474 PString authRealm;
00475 PString username;
00476 PString password;
00477 PString nonce;
00478 Algorithm algorithm;
00479 };
00480
00481
00483
00484
00490 class SIP_PDU : public PObject
00491 {
00492 PCLASSINFO(SIP_PDU, PObject);
00493 public:
00494 enum Methods {
00495 Method_INVITE,
00496 Method_ACK,
00497 Method_OPTIONS,
00498 Method_BYE,
00499 Method_CANCEL,
00500 Method_REGISTER,
00501 Method_SUBSCRIBE,
00502 Method_NOTIFY,
00503 Method_REFER,
00504 Method_MESSAGE,
00505 NumMethods
00506 };
00507
00508 enum StatusCodes {
00509 IllegalStatusCode,
00510
00511 Information_Trying = 100,
00512 Information_Ringing = 180,
00513 Information_CallForwarded = 181,
00514 Information_Queued = 182,
00515 Information_Session_Progress = 183,
00516
00517 Successful_OK = 200,
00518 Successful_Accepted = 202,
00519
00520 Redirection_MultipleChoices = 300,
00521 Redirection_MovedPermanently = 301,
00522 Redirection_MovedTemporarily = 302,
00523 Redirection_UseProxy = 305,
00524 Redirection_AlternativeService = 380,
00525
00526 Failure_BadRequest = 400,
00527 Failure_UnAuthorised = 401,
00528 Failure_PaymentRequired = 402,
00529 Failure_Forbidden = 403,
00530 Failure_NotFound = 404,
00531 Failure_MethodNotAllowed = 405,
00532 Failure_NotAcceptable = 406,
00533 Failure_ProxyAuthenticationRequired = 407,
00534 Failure_RequestTimeout = 408,
00535 Failure_Conflict = 409,
00536 Failure_Gone = 410,
00537 Failure_LengthRequired = 411,
00538 Failure_RequestEntityTooLarge = 413,
00539 Failure_RequestURITooLong = 414,
00540 Failure_UnsupportedMediaType = 415,
00541 Failure_UnsupportedURIScheme = 416,
00542 Failure_BadExtension = 420,
00543 Failure_ExtensionRequired = 421,
00544 Failure_IntervalTooBrief = 423,
00545 Failure_TemporarilyUnavailable = 480,
00546 Failure_TransactionDoesNotExist = 481,
00547 Failure_LoopDetected = 482,
00548 Failure_TooManyHops = 483,
00549 Failure_AddressIncomplete = 484,
00550 Failure_Ambiguous = 485,
00551 Failure_BusyHere = 486,
00552 Failure_RequestTerminated = 487,
00553 Failure_NotAcceptableHere = 488,
00554 Failure_BadEvent = 489,
00555 Failure_RequestPending = 491,
00556 Failure_Undecipherable = 493,
00557
00558 Failure_InternalServerError = 500,
00559 Failure_NotImplemented = 501,
00560 Failure_BadGateway = 502,
00561 Failure_ServiceUnavailable = 503,
00562 Failure_ServerTimeout = 504,
00563 Failure_SIPVersionNotSupported = 505,
00564 Failure_MessageTooLarge = 513,
00565
00566 GlobalFailure_BusyEverywhere = 600,
00567 GlobalFailure_Decline = 603,
00568 GlobalFailure_DoesNotExistAnywhere = 604,
00569 GlobalFailure_NotAcceptable = 606,
00570
00571 MaxStatusCode = 699
00572 };
00573
00574 static const char * GetStatusCodeDescription (int code);
00575
00576 enum {
00577 MaxSize = 65535
00578 };
00579
00580 SIP_PDU();
00581
00584 SIP_PDU(
00585 Methods method,
00586 const SIPURL & dest,
00587 const PString & to,
00588 const PString & from,
00589 const PString & callID,
00590 unsigned cseq,
00591 const OpalTransportAddress & via
00592 );
00595 SIP_PDU(
00596 Methods method,
00597 SIPConnection & connection,
00598 const OpalTransport & transport
00599 );
00600
00604 SIP_PDU(
00605 const SIP_PDU & request,
00606 StatusCodes code,
00607 const char * contact = NULL,
00608 const char * extra = NULL
00609 );
00610 SIP_PDU(const SIP_PDU &);
00611 SIP_PDU & operator=(const SIP_PDU &);
00612 ~SIP_PDU();
00613
00614 void PrintOn(
00615 ostream & strm
00616 ) const;
00617
00618 void Construct(
00619 Methods method
00620 );
00621 void Construct(
00622 Methods method,
00623 const SIPURL & dest,
00624 const PString & to,
00625 const PString & from,
00626 const PString & callID,
00627 unsigned cseq,
00628 const OpalTransportAddress & via
00629 );
00630 void Construct(
00631 Methods method,
00632 SIPConnection & connection,
00633 const OpalTransport & transport
00634 );
00635
00640 BOOL SetRoute(SIPConnection & connection);
00641
00644 void SetAllow(void);
00645
00648 void AdjustVia(OpalTransport & transport);
00649
00653 OpalTransportAddress GetViaAddress(OpalEndPoint &);
00654
00658 OpalTransportAddress GetSendAddress(SIPConnection &);
00659
00662 BOOL Read(
00663 OpalTransport & transport
00664 );
00665
00668 BOOL Write(
00669 OpalTransport & transport
00670 );
00671
00672 PString GetTransactionID() const;
00673
00674 Methods GetMethod() const { return method; }
00675 StatusCodes GetStatusCode () const { return statusCode; }
00676 const SIPURL & GetURI() const { return uri; }
00677 unsigned GetVersionMajor() const { return versionMajor; }
00678 unsigned GetVersionMinor() const { return versionMinor; }
00679 const PString & GetEntityBody() const { return entityBody; }
00680 const PString & GetInfo() const { return info; }
00681 const SIPMIMEInfo & GetMIME() const { return mime; }
00682 SIPMIMEInfo & GetMIME() { return mime; }
00683 BOOL HasSDP() const { return sdp != NULL; }
00684 SDPSessionDescription & GetSDP() const { return *PAssertNULL(sdp); }
00685 void SetSDP(SDPSessionDescription * s) { sdp = s; }
00686 void SetSDP(const SDPSessionDescription & s) { sdp = new SDPSessionDescription(s); }
00687
00688 protected:
00689
00690 Methods method;
00691 StatusCodes statusCode;
00692 SIPURL uri;
00693 unsigned versionMajor;
00694 unsigned versionMinor;
00695 PString info;
00696 SIPMIMEInfo mime;
00697 PString entityBody;
00698
00699 SDPSessionDescription * sdp;
00700 };
00701
00702
00703 PQUEUE(SIP_PDU_Queue, SIP_PDU);
00704
00705
00707
00708
00719 class SIPTransaction : public SIP_PDU
00720 {
00721 PCLASSINFO(SIPTransaction, SIP_PDU);
00722 public:
00723 SIPTransaction(
00724 SIPEndPoint & endpoint,
00725 OpalTransport & transport
00726 );
00730 SIPTransaction(
00731 SIPConnection & connection,
00732 OpalTransport & transport,
00733 Methods method = NumMethods
00734 );
00735 ~SIPTransaction();
00736
00737 BOOL Start();
00738 BOOL IsInProgress() const { return state == Trying && state == Proceeding; }
00739 BOOL IsFailed() const { return state > Terminated_Success; }
00740 BOOL IsFinished() { return finished.Wait(0); }
00741 void Wait();
00742 BOOL SendCANCEL();
00743
00744 virtual BOOL OnReceivedResponse(SIP_PDU & response);
00745 virtual BOOL OnCompleted(SIP_PDU & response);
00746
00747 OpalTransport & GetTransport() const { return transport; }
00748 SIPConnection * GetConnection() const { return connection; }
00749
00750 const OpalTransportAddress & GetLocalAddress() const { return localAddress; }
00751
00752 protected:
00753 void Construct();
00754 BOOL ResendCANCEL();
00755
00756 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnRetry);
00757 PDECLARE_NOTIFIER(PTimer, SIPTransaction, OnTimeout);
00758
00759 enum States {
00760 NotStarted,
00761 Trying,
00762 Proceeding,
00763 Cancelling,
00764 Completed,
00765 Terminated_Success,
00766 Terminated_Timeout,
00767 Terminated_RetriesExceeded,
00768 Terminated_TransportError,
00769 Terminated_Cancelled,
00770 NumStates
00771 };
00772 void SetTerminated(States newState);
00773
00774 SIPEndPoint & endpoint;
00775 OpalTransport & transport;
00776 SIPConnection * connection;
00777
00778 States state;
00779 unsigned retry;
00780 PTimer retryTimer;
00781 PTimer completionTimer;
00782
00783 PSyncPoint finished;
00784 PTimedMutex mutex;
00785
00786 OpalTransportAddress localAddress;
00787 };
00788
00789
00790 PLIST(SIPTransactionList, SIPTransaction);
00791 PDICTIONARY(SIPTransactionDict, PString, SIPTransaction);
00792
00793
00795
00796
00802 class SIPInvite : public SIPTransaction
00803 {
00804 PCLASSINFO(SIPInvite, SIPTransaction);
00805 public:
00806 SIPInvite(
00807 SIPConnection & connection,
00808 OpalTransport & transport
00809 );
00810 SIPInvite(
00811 SIPConnection & connection,
00812 OpalTransport & transport,
00813 RTP_SessionManager & sm
00814 );
00815
00816 virtual BOOL OnReceivedResponse(SIP_PDU & response);
00817
00818 RTP_SessionManager & GetSessionManager() { return rtpSessions; }
00819
00820 protected:
00821 RTP_SessionManager rtpSessions;
00822 };
00823
00824
00826
00827 class SIPRegister : public SIPTransaction
00828 {
00829 PCLASSINFO(SIPRegister, SIPTransaction);
00830 public:
00831 SIPRegister(
00832 SIPEndPoint & endpoint,
00833 OpalTransport & transport,
00834 const SIPURL & address,
00835 const PString & id,
00836 unsigned expires
00837 );
00838 };
00839
00840
00842
00843 class SIPMWISubscribe : public SIPTransaction
00844 {
00845 PCLASSINFO(SIPMWISubscribe, SIPTransaction);
00846 public:
00849 enum MWIType {
00850
00851 VoiceMessage,
00852 FaxMessage,
00853 PagerMessage,
00854 MultimediaMessage,
00855 TextMessage,
00856 None
00857 };
00858
00859 SIPMWISubscribe(
00860 SIPEndPoint & endpoint,
00861 OpalTransport & transport,
00862 const SIPURL & address,
00863 const PString & id,
00864 unsigned expires
00865 );
00866 };
00867
00868
00870
00871 class SIPRefer : public SIPTransaction
00872 {
00873 PCLASSINFO(SIPRefer, SIPTransaction);
00874 public:
00875 SIPRefer(
00876 SIPConnection & connection,
00877 OpalTransport & transport,
00878 const PString & refer
00879 );
00880 };
00881
00882
00884
00885
00886
00887
00888 class SIPReferNotify : public SIPTransaction
00889 {
00890 PCLASSINFO(SIPReferNotify, SIPTransaction);
00891 public:
00892 SIPReferNotify(
00893 SIPConnection & connection,
00894 OpalTransport & transport,
00895 StatusCodes code
00896 );
00897 };
00898
00899
00901
00902
00903
00904 class SIPMessage : public SIPTransaction
00905 {
00906 PCLASSINFO(SIPMessage, SIPTransaction);
00907
00908 public:
00909 SIPMessage(
00910 SIPEndPoint & ep,
00911 OpalTransport & trans,
00912 const SIPURL & address,
00913 const PString & body
00914 );
00915 };
00916
00917
00919
00920
00921
00922
00923 class SIPAck : public SIP_PDU
00924 {
00925 PCLASSINFO(SIPAck, SIP_PDU);
00926 public:
00927
00928 SIPAck(
00929 SIPEndPoint & ep,
00930 SIPTransaction & invite,
00931 SIP_PDU & response);
00932
00933
00934 SIPAck(
00935 SIPTransaction & invite);
00936
00937 protected:
00938 void Construct();
00939
00940 SIPTransaction & transaction;
00941 };
00942
00943
00945
00946
00947
00948 class SIPOptions : public SIPTransaction
00949 {
00950 PCLASSINFO(SIPOptions, SIPTransaction);
00951
00952 public:
00953 SIPOptions(
00954 SIPEndPoint & ep,
00955 OpalTransport & trans,
00956 const SIPURL & address
00957 );
00958 };
00959
00960
00961 #endif // __OPAL_SIPPDU_H
00962
00963
00964