1 /* 2 * handlers.h 3 * 4 * Session Initiation Protocol endpoint. 5 * 6 * Open Phone Abstraction Library (OPAL) 7 * 8 * Copyright (c) 2000 Equivalence Pty. Ltd. 9 * 10 * The contents of this file are subject to the Mozilla Public License 11 * Version 1.0 (the "License"); you may not use this file except in 12 * compliance with the License. You may obtain a copy of the License at 13 * http://www.mozilla.org/MPL/ 14 * 15 * Software distributed under the License is distributed on an "AS IS" 16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 17 * the License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * The Original Code is Open Phone Abstraction Library. 21 * 22 * The Initial Developer of the Original Code is Damien Sandras. 23 * 24 * Contributor(s): ______________________________________. 25 * 26 * $Revision: 28428 $ 27 * $Author: rjongbloed $ 28 * $Date: 2012-10-01 03:38:50 -0500 (Mon, 01 Oct 2012) $ 29 */ 30 31 #ifndef OPAL_SIP_HANDLERS_H 32 #define OPAL_SIP_HANDLERS_H 33 34 #ifdef P_USE_PRAGMA 35 #pragma interface 36 #endif 37 38 #ifndef _PTLIB_H 39 #include <ptlib.h> 40 #endif 41 42 #include <opal/buildopts.h> 43 44 #if OPAL_SIP 45 46 #include <opal/pres_ent.h> 47 #include <opal/connection.h> 48 #include <sip/sippdu.h> 49 50 51 /* Class to handle SIP REGISTER, SUBSCRIBE, MESSAGE, and renew 52 * the 'bindings' before they expire. 53 */ 54 class SIPHandler : public PSafeObject 55 { 56 PCLASSINFO(SIPHandler, PSafeObject); 57 58 protected: 59 SIPHandler( 60 SIP_PDU::Methods method, 61 SIPEndPoint & ep, 62 const SIPParameters & params 63 ); 64 65 public: 66 ~SIPHandler(); 67 68 virtual Comparison Compare(const PObject & other) const; 69 70 virtual bool ShutDown(); 71 72 enum State { 73 Subscribed, // The registration is active 74 Subscribing, // The registration is in process 75 Unavailable, // The registration is offline and still being attempted 76 Refreshing, // The registration is being refreshed 77 Restoring, // The registration is trying to be restored after being offline 78 Unsubscribing, // The unregistration is in process 79 Unsubscribed, // The registrating is inactive 80 NumStates 81 }; 82 83 void SetState (SIPHandler::State s); 84 GetState()85 inline SIPHandler::State GetState () 86 { return m_state; } 87 88 virtual OpalTransport * GetTransport(); 89 GetAuthentication()90 virtual SIPAuthentication * GetAuthentication() 91 { return m_authentication; } 92 GetAddressOfRecord()93 virtual const SIPURL & GetAddressOfRecord() 94 { return m_addressOfRecord; } 95 96 virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response); 97 98 virtual void SetExpire(int e); 99 GetExpire()100 virtual int GetExpire() 101 { return m_currentExpireTime; } 102 GetCallID()103 virtual const PString & GetCallID() const 104 { return m_callID; } 105 SetBody(const PString &)106 virtual void SetBody(const PString & /*body*/) { } 107 IsDuplicateCSeq(unsigned)108 virtual bool IsDuplicateCSeq(unsigned ) { return false; } 109 110 virtual SIPTransaction * CreateTransaction(OpalTransport & t) = 0; 111 GetMethod()112 SIP_PDU::Methods GetMethod() const { return m_method; } GetEventPackage()113 virtual SIPSubscribe::EventPackage GetEventPackage() const { return SIPEventPackage(); } 114 115 virtual void OnReceivedResponse(SIPTransaction & transaction, SIP_PDU & response); 116 virtual void OnReceivedIntervalTooBrief(SIPTransaction & transaction, SIP_PDU & response); 117 virtual void OnReceivedTemporarilyUnavailable(SIPTransaction & transaction, SIP_PDU & response); 118 virtual void OnReceivedAuthenticationRequired(SIPTransaction & transaction, SIP_PDU & response); 119 virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response); 120 virtual void OnTransactionFailed(SIPTransaction & transaction); 121 122 virtual void OnFailed(const SIP_PDU & response); 123 virtual void OnFailed(SIP_PDU::StatusCodes); 124 125 bool ActivateState(SIPHandler::State state); SendNotify(const PObject *)126 virtual bool SendNotify(const PObject * /*body*/) { return false; } 127 GetEndPoint()128 SIPEndPoint & GetEndPoint() const { return endpoint; } 129 GetProductInfo()130 const OpalProductInfo & GetProductInfo() const { return m_productInfo; } 131 GetUsername()132 const PString & GetUsername() const { return m_username; } GetPassword()133 const PString & GetPassword() const { return m_password; } GetRealm()134 const PString & GetRealm() const { return m_realm; } GetRemoteAddress()135 const SIPURL & GetRemoteAddress() const { return m_remoteAddress; } GetProxy()136 const SIPURL & GetProxy() const { return m_proxy; } 137 138 SIPMIMEInfo m_mime; 139 140 protected: 141 virtual PBoolean SendRequest(SIPHandler::State state); 142 void RetryLater(unsigned after); 143 PDECLARE_NOTIFIER(PTimer, SIPHandler, OnExpireTimeout); 144 static PBoolean WriteSIPHandler(OpalTransport & transport, void * info); 145 virtual bool WriteSIPHandler(OpalTransport & transport, bool forked); 146 147 SIPEndPoint & endpoint; 148 149 SIPAuthentication * m_authentication; 150 unsigned m_authenticateErrors; 151 PString m_username; 152 PString m_password; 153 PString m_realm; 154 155 PSafeList<SIPTransaction> m_transactions; 156 OpalTransport * m_transport; 157 158 SIP_PDU::Methods m_method; 159 SIPURL m_addressOfRecord; 160 SIPURL m_remoteAddress; 161 PString m_callID; 162 unsigned m_lastCseq; 163 int m_currentExpireTime; 164 int m_originalExpireTime; 165 int m_offlineExpireTime; 166 State m_state; 167 queue<State> m_stateQueue; 168 bool m_receivedResponse; 169 PTimer m_expireTimer; 170 SIPURL m_proxy; 171 OpalProductInfo m_productInfo; 172 173 // Keep a copy of the keys used for easy removal on destruction 174 typedef std::map<PString, PSafePtr<SIPHandler> > IndexMap; 175 std::pair<IndexMap::iterator, bool> m_byCallID; 176 std::pair<IndexMap::iterator, bool> m_byAorAndPackage; 177 std::pair<IndexMap::iterator, bool> m_byAuthIdAndRealm; 178 std::pair<IndexMap::iterator, bool> m_byAorUserAndRealm; 179 180 friend class SIPHandlersList; 181 }; 182 183 #if PTRACING 184 ostream & operator<<(ostream & strm, SIPHandler::State state); 185 #endif 186 187 188 class SIPRegisterHandler : public SIPHandler 189 { 190 PCLASSINFO(SIPRegisterHandler, SIPHandler); 191 192 public: 193 SIPRegisterHandler( 194 SIPEndPoint & ep, 195 const SIPRegister::Params & params 196 ); 197 198 virtual SIPTransaction * CreateTransaction(OpalTransport &); 199 virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response); 200 201 virtual void OnFailed(SIP_PDU::StatusCodes r); 202 203 void UpdateParameters(const SIPRegister::Params & params); 204 GetParams()205 const SIPRegister::Params & GetParams() const { return m_parameters; } 206 GetContacts()207 const SIPURLList & GetContacts() const { return m_contactAddresses; } GetServiceRoute()208 const SIPURLList & GetServiceRoute() const { return m_serviceRoute; } 209 210 protected: 211 virtual PBoolean SendRequest(SIPHandler::State state); 212 void SendStatus(SIP_PDU::StatusCodes code, State state); 213 214 SIPRegister::Params m_parameters; 215 unsigned m_sequenceNumber; 216 SIPURLList m_contactAddresses; 217 SIPURLList m_serviceRoute; 218 OpalTransportAddress m_externalAddress; 219 }; 220 221 222 class SIPSubscribeHandler : public SIPHandler 223 { 224 PCLASSINFO(SIPSubscribeHandler, SIPHandler); 225 public: 226 SIPSubscribeHandler(SIPEndPoint & ep, const SIPSubscribe::Params & params); 227 ~SIPSubscribeHandler(); 228 229 virtual SIPTransaction * CreateTransaction (OpalTransport &); 230 virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response); 231 virtual PBoolean OnReceivedNOTIFY(SIP_PDU & response); 232 virtual void OnFailed(const SIP_PDU & response); GetEventPackage()233 virtual SIPEventPackage GetEventPackage() const 234 { return m_parameters.m_eventPackage; } 235 236 void UpdateParameters(const SIPSubscribe::Params & params); 237 IsDuplicateCSeq(unsigned sequenceNumber)238 virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); } 239 GetParams()240 const SIPSubscribe::Params & GetParams() const { return m_parameters; } 241 242 protected: 243 virtual PBoolean SendRequest(SIPHandler::State state); 244 virtual bool WriteSIPHandler(OpalTransport & transport, bool forked); 245 void SendStatus(SIP_PDU::StatusCodes code, State state); 246 bool DispatchNOTIFY(SIP_PDU & request, SIP_PDU & response); 247 248 SIPSubscribe::Params m_parameters; 249 SIPDialogContext m_dialog; 250 bool m_unconfirmed; 251 SIPEventPackageHandler * m_packageHandler; 252 253 SIP_PDU * m_previousResponse; 254 }; 255 256 257 class SIPNotifyHandler : public SIPHandler 258 { 259 PCLASSINFO(SIPNotifyHandler, SIPHandler); 260 public: 261 SIPNotifyHandler( 262 SIPEndPoint & ep, 263 const PString & targetAddress, 264 const SIPEventPackage & eventPackage, 265 const SIPDialogContext & dialog 266 ); 267 ~SIPNotifyHandler(); 268 269 virtual SIPTransaction * CreateTransaction(OpalTransport &); GetEventPackage()270 virtual SIPEventPackage GetEventPackage() const 271 { return m_eventPackage; } 272 SetBody(const PString & body)273 virtual void SetBody(const PString & body) { m_body = body; } 274 IsDuplicateCSeq(unsigned sequenceNumber)275 virtual bool IsDuplicateCSeq(unsigned sequenceNumber) { return m_dialog.IsDuplicateCSeq(sequenceNumber); } 276 virtual bool SendNotify(const PObject * body); 277 278 enum Reasons { 279 Deactivated, 280 Probation, 281 Rejected, 282 Timeout, 283 GiveUp, 284 NoResource 285 }; 286 287 protected: 288 virtual PBoolean SendRequest(SIPHandler::State state); 289 virtual bool WriteSIPHandler(OpalTransport & transport, bool forked); 290 291 SIPEventPackage m_eventPackage; 292 SIPDialogContext m_dialog; 293 Reasons m_reason; 294 SIPEventPackageHandler * m_packageHandler; 295 PString m_body; 296 }; 297 298 299 class SIPPublishHandler : public SIPHandler 300 { 301 PCLASSINFO(SIPPublishHandler, SIPHandler); 302 303 public: 304 SIPPublishHandler(SIPEndPoint & ep, 305 const SIPSubscribe::Params & params, 306 const PString & body); 307 SetBody(const PString & body)308 virtual void SetBody(const PString & body) { m_body = body; } 309 310 virtual SIPTransaction * CreateTransaction(OpalTransport &); 311 virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response); GetEventPackage()312 virtual SIPEventPackage GetEventPackage() const { return m_parameters.m_eventPackage; } 313 314 protected: 315 SIPSubscribe::Params m_parameters; 316 PString m_body; 317 PString m_sipETag; 318 }; 319 320 321 class SIPMessageHandler : public SIPHandler 322 { 323 PCLASSINFO(SIPMessageHandler, SIPHandler); 324 public: 325 SIPMessageHandler(SIPEndPoint & ep, const SIPMessage::Params & params); 326 327 virtual SIPTransaction * CreateTransaction (OpalTransport &); 328 virtual void OnFailed(SIP_PDU::StatusCodes); 329 virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response); 330 331 void UpdateParameters(const SIPMessage::Params & params); 332 333 protected: 334 SIPMessage::Params m_parameters; 335 }; 336 337 338 class SIPOptionsHandler : public SIPHandler 339 { 340 PCLASSINFO(SIPOptionsHandler, SIPHandler); 341 public: 342 SIPOptionsHandler(SIPEndPoint & ep, const SIPOptions::Params & params); 343 344 virtual SIPTransaction * CreateTransaction (OpalTransport &); 345 virtual void OnFailed(SIP_PDU::StatusCodes); 346 virtual void OnFailed(const SIP_PDU & response); 347 virtual void OnReceivedOK(SIPTransaction & transaction, SIP_PDU & response); 348 349 protected: 350 SIPOptions::Params m_parameters; 351 }; 352 353 354 class SIPPingHandler : public SIPHandler 355 { 356 PCLASSINFO(SIPPingHandler, SIPHandler); 357 public: 358 SIPPingHandler(SIPEndPoint & ep, const PURL & to); 359 virtual SIPTransaction * CreateTransaction (OpalTransport &); 360 }; 361 362 363 /** This dictionary is used both to contain the active and successful 364 * registrations, and subscriptions. 365 */ 366 class SIPHandlersList 367 { 368 public: 369 /** Append a new handler to the list 370 */ 371 void Append(SIPHandler * handler); 372 373 /** Remove a handler from the list. 374 Handler is not immediately deleted but marked for deletion later by 375 DeleteObjectsToBeRemoved() when all references are done with the handler. 376 */ 377 void Remove(SIPHandler * handler); 378 379 /** Update indexes for handler in the list 380 */ 381 void Update(SIPHandler * handler); 382 383 /** Clean up lists of handler. 384 */ DeleteObjectsToBeRemoved()385 bool DeleteObjectsToBeRemoved() 386 { return m_handlersList.DeleteObjectsToBeRemoved(); } 387 388 /** Get the first handler in the list. Further enumeration may be done by 389 the ++operator on the safe pointer. 390 */ 391 PSafePtr<SIPHandler> GetFirstHandler(PSafetyMode mode = PSafeReference) const 392 { return PSafePtr<SIPHandler>(m_handlersList, mode); } 393 394 /** 395 * Return the number of registered accounts 396 */ 397 unsigned GetCount(SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const; 398 399 /** 400 * Return a list of the active address of records for each handler. 401 */ 402 PStringList GetAddresses(bool includeOffline, SIP_PDU::Methods meth, const PString & eventPackage = PString::Empty()) const; 403 404 /** 405 * Find the SIPHandler object with the specified callID 406 */ 407 PSafePtr<SIPHandler> FindSIPHandlerByCallID(const PString & callID, PSafetyMode m); 408 409 /** 410 * Find the SIPHandler object with the specified authRealm 411 */ 412 PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, PSafetyMode m); 413 414 /** 415 * Find the SIPHandler object with the specified authRealm & user 416 */ 417 PSafePtr<SIPHandler> FindSIPHandlerByAuthRealm(const PString & authRealm, const PString & userName, PSafetyMode m); 418 419 /** 420 * Find the SIPHandler object with the specified URL. The url is 421 * the registration address, for example, 6001@sip.seconix.com 422 * when registering 6001 to sip.seconix.com with realm seconix.com 423 * or 6001@seconix.com when registering 6001@seconix.com to 424 * sip.seconix.com 425 */ 426 PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, PSafetyMode m); 427 PSafePtr<SIPHandler> FindSIPHandlerByUrl(const PURL & url, SIP_PDU::Methods meth, const PString & eventPackage, PSafetyMode m); 428 429 /** 430 * Find the SIPHandler object with the specified registration host. 431 * For example, in the above case, the name parameter 432 * could be "sip.seconix.com" or "seconix.com". 433 */ 434 PSafePtr <SIPHandler> FindSIPHandlerByDomain(const PString & name, SIP_PDU::Methods meth, PSafetyMode m); 435 436 protected: 437 void RemoveIndexes(SIPHandler * handler); 438 439 PMutex m_extraMutex; 440 PSafeList<SIPHandler> m_handlersList; 441 442 typedef SIPHandler::IndexMap IndexMap; 443 PSafePtr<SIPHandler> FindBy(IndexMap & by, const PString & key, PSafetyMode m); 444 445 IndexMap m_byCallID; 446 IndexMap m_byAorAndPackage; 447 IndexMap m_byAuthIdAndRealm; 448 IndexMap m_byAorUserAndRealm; 449 }; 450 451 452 /** Information for SIP "presence" event package notification messages. 453 */ 454 class SIPPresenceInfo : public OpalPresenceInfo 455 { 456 public: 457 SIPPresenceInfo( 458 State state = Unchanged 459 ); 460 461 // basic presence defined by RFC 3863 462 PString m_tupleId; 463 PString m_contact; 464 465 // presence extensions defined by RFC 4480 466 PStringArray m_activities; // list of activities, seperated by newline 467 468 // presence agent 469 PString m_presenceAgent; 470 471 PString AsXML() const; 472 473 #if P_EXPAT 474 static bool ParseXML( 475 const PString & body, 476 list<SIPPresenceInfo> & info, 477 PString & error 478 ); 479 #endif 480 481 void PrintOn(ostream & strm) const; 482 friend ostream & operator<<(ostream & strm, const SIPPresenceInfo & info) { info.PrintOn(strm); return strm; } 483 484 static State FromSIPActivityString(const PString & str); 485 486 static bool AsSIPActivityString(State state, PString & str); 487 bool AsSIPActivityString(PString & str) const; 488 489 PString m_personId; 490 }; 491 492 493 /** Information for SIP "dialog" event package notification messages. 494 */ 495 struct SIPDialogNotification : public PObject 496 { 497 PCLASSINFO(SIPDialogNotification, PObject); 498 499 enum States { 500 Terminated, 501 Trying, 502 Proceeding, 503 Early, 504 Confirmed, 505 506 FirstState = Terminated, 507 LastState = Confirmed 508 }; 509 friend States operator++(States & state) { return (state = (States)(state+1)); } 510 friend States operator--(States & state) { return (state = (States)(state-1)); } 511 static PString GetStateName(States state); GetStateNameSIPDialogNotification512 PString GetStateName() const { return GetStateName(m_state); } 513 514 enum Events { 515 NoEvent = -1, 516 Cancelled, 517 Rejected, 518 Replaced, 519 LocalBye, 520 RemoteBye, 521 Error, 522 Timeout, 523 524 FirstEvent = Cancelled, 525 LastEvent = Timeout 526 }; 527 friend Events operator++(Events & evt) { return (evt = (Events)(evt+1)); } 528 friend Events operator--(Events & evt) { return (evt = (Events)(evt-1)); } 529 static PString GetEventName(Events state); GetEventNameSIPDialogNotification530 PString GetEventName() const { return GetEventName(m_eventType); } 531 532 enum Rendering { 533 RenderingUnknown = -1, 534 NotRenderingMedia, 535 RenderingMedia 536 }; 537 538 PString m_entity; 539 PString m_dialogId; 540 PString m_callId; 541 bool m_initiator; 542 States m_state; 543 Events m_eventType; 544 unsigned m_eventCode; 545 struct Participant { ParticipantSIPDialogNotification::Participant546 Participant() : m_appearance(-1), m_byeless(false), m_rendering(RenderingUnknown) { } 547 PString m_URI; 548 PString m_dialogTag; 549 PString m_identity; 550 PString m_display; 551 int m_appearance; 552 bool m_byeless; 553 Rendering m_rendering; 554 } m_local, m_remote; 555 556 SIPDialogNotification(const PString & entity = PString::Empty()); 557 558 void PrintOn(ostream & strm) const; 559 }; 560 561 562 #endif // OPAL_SIP 563 564 #endif // OPAL_SIP_HANDLERS_H 565