1 /* 2 * localep.h 3 * 4 * Local EndPoint/Connection. 5 * 6 * Open Phone Abstraction Library (OPAL) 7 * Formally known as the Open H323 project. 8 * 9 * Copyright (c) 2008 Vox Lucida Pty. Ltd. 10 * 11 * The contents of this file are subject to the Mozilla Public License 12 * Version 1.0 (the "License"); you may not use this file except in 13 * compliance with the License. You may obtain a copy of the License at 14 * http://www.mozilla.org/MPL/ 15 * 16 * Software distributed under the License is distributed on an "AS IS" 17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 18 * the License for the specific language governing rights and limitations 19 * under the License. 20 * 21 * The Original Code is Open Phone Abstraction Library. 22 * 23 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 24 * 25 * Contributor(s): ______________________________________. 26 * 27 * $Revision: 28040 $ 28 * $Author: rjongbloed $ 29 * $Date: 2012-07-16 01:23:59 -0500 (Mon, 16 Jul 2012) $ 30 */ 31 32 #ifndef OPAL_OPAL_LOCALEP_H 33 #define OPAL_OPAL_LOCALEP_H 34 35 #ifdef P_USE_PRAGMA 36 #pragma interface 37 #endif 38 39 #include <opal/buildopts.h> 40 41 #include <opal/endpoint.h> 42 43 class OpalLocalConnection; 44 45 46 /** Local EndPoint. 47 This class represents an endpoint on the local machine that can receive 48 media via virtual functions. 49 */ 50 class OpalLocalEndPoint : public OpalEndPoint 51 { 52 PCLASSINFO(OpalLocalEndPoint, OpalEndPoint); 53 public: 54 /**@name Construction */ 55 //@{ 56 /**Create a new endpoint. 57 */ 58 OpalLocalEndPoint( 59 OpalManager & manager, ///< Manager of all endpoints. 60 const char * prefix = "local" ///< Prefix for URL style address strings 61 ); 62 63 /**Destroy endpoint. 64 */ 65 ~OpalLocalEndPoint(); 66 //@} 67 68 /**@name Overrides from OpalEndPoint */ 69 //@{ 70 /**Get the data formats this endpoint is capable of operating. 71 This provides a list of media data format names that may be used by an 72 OpalMediaStream may be created by a connection from this endpoint. 73 74 Note that a specific connection may not actually support all of the 75 media formats returned here, but should return no more. 76 77 The default behaviour returns the most basic media formats, PCM audio 78 and YUV420P video. 79 */ 80 virtual OpalMediaFormatList GetMediaFormats() const; 81 82 /**Set up a connection to a remote party. 83 This is called from the OpalManager::MakeConnection() function once 84 it has determined that this is the endpoint for the protocol. 85 86 The general form for this party parameter is: 87 88 [proto:][alias@][transport$]address[:port] 89 90 where the various fields will have meanings specific to the endpoint 91 type. For example, with H.323 it could be "h323:Fred@site.com" which 92 indicates a user Fred at gatekeeper size.com. Whereas for the PSTN 93 endpoint it could be "pstn:5551234" which is to call 5551234 on the 94 first available PSTN line. 95 96 The proto field is optional when passed to a specific endpoint. If it 97 is present, however, it must agree with the endpoints protocol name or 98 false is returned. 99 100 This function usually returns almost immediately with the connection 101 continuing to occur in a new background thread. 102 103 If false is returned then the connection could not be established. For 104 example if a PSTN endpoint is used and the assiciated line is engaged 105 then it may return immediately. Returning a non-NULL value does not 106 mean that the connection will succeed, only that an attempt is being 107 made. 108 109 The default behaviour is pure. 110 */ 111 virtual PSafePtr<OpalConnection> MakeConnection( 112 OpalCall & call, ///< Owner of connection 113 const PString & party, ///< Remote party to call 114 void * userData = NULL, ///< Arbitrary data to pass to connection 115 unsigned int options = 0, ///< options to pass to conneciton 116 OpalConnection::StringOptions * stringOptions = NULL ///< Options to pass to connection 117 ); 118 //@} 119 120 /**@name Customisation call backs */ 121 //@{ 122 /**Find a connection that uses the specified token. 123 This searches the endpoint for the connection that contains the token 124 as provided by functions such as MakeConnection(). If not then it 125 attempts to use the token as a OpalCall token and find a connection 126 of the same class. 127 */ 128 PSafePtr<OpalLocalConnection> GetLocalConnectionWithLock( 129 const PString & token, ///< Token to identify connection 130 PSafetyMode mode = PSafeReadWrite ///< Lock mode 131 ) { return GetConnectionWithLockAs<OpalLocalConnection>(token, mode); } 132 133 /**Create a connection for the PCSS endpoint. 134 The default implementation is to create a OpalLocalConnection. 135 */ 136 virtual OpalLocalConnection * CreateConnection( 137 OpalCall & call, ///< Owner of connection 138 void * userData, ///< Arbitrary data to pass to connection 139 unsigned options, ///< Option bit mask to pass to connection 140 OpalConnection::StringOptions * stringOptions ///< Options to pass to connection 141 ); 142 143 /**Call back just before remote is contacted. 144 If false is returned the call is aborted with EndedByNoAccept. 145 146 The default implementation returns true. 147 */ 148 virtual bool OnOutgoingSetUp( 149 const OpalLocalConnection & connection ///< Connection having event 150 ); 151 152 /**Call back to indicate that remote is ringing. 153 If false is returned the call is aborted. 154 155 The default implementation does nothing. 156 */ 157 virtual bool OnOutgoingCall( 158 const OpalLocalConnection & connection ///< Connection having event 159 ); 160 161 /**Call back to indicate that there is an incoming call. 162 Note this function should not block or it will impede the operation of 163 the stack. 164 165 The default implementation returns true; 166 167 @return false is returned the call is aborted with status of EndedByLocalBusy. 168 */ 169 virtual bool OnIncomingCall( 170 OpalLocalConnection & connection ///< Connection having event 171 ); 172 173 /**Indicate alerting for the incoming connection. 174 Returns false if the connection token does not correspond to a valid 175 connection. 176 */ 177 virtual bool AlertingIncomingCall( 178 const PString & token, ///< Token of connection to indicate alerting 179 OpalConnection::StringOptions * options = NULL ///< Optional string optiosn to apply 180 ); 181 182 /**Accept the incoming connection. 183 Returns false if the connection token does not correspond to a valid 184 connection. 185 */ 186 virtual bool AcceptIncomingCall( 187 const PString & token, ///< Token of connection to accept call 188 OpalConnection::StringOptions * options = NULL ///< Optional string optiosn to apply 189 ); 190 191 /**Reject the incoming connection. 192 Returns false if the connection token does not correspond to a valid 193 connection. 194 */ 195 virtual bool RejectIncomingCall( 196 const PString & token, ///< Token of connection to accept call 197 const OpalConnection::CallEndReason & reason = OpalConnection::EndedByAnswerDenied ///< Reason for rejecting the call 198 ); 199 200 /**Call back to indicate that the remote user has indicated something. 201 If false is returned the call is aborted. 202 203 The default implementation does nothing. 204 */ 205 virtual bool OnUserInput( 206 const OpalLocalConnection & connection, ///< Connection having event 207 const PString & indication ///< User input received 208 ); 209 210 /**Call back to get media data for transmission. 211 If false is returned then OnReadMediaData() is called. 212 213 Care with the handling of real time is rqeuired, see GetSynchronicity 214 for more details. 215 216 The default implementation returns false. 217 */ 218 virtual bool OnReadMediaFrame( 219 const OpalLocalConnection & connection, ///< Connection for media 220 const OpalMediaStream & mediaStream, ///< Media stream data is required for 221 RTP_DataFrame & frame ///< RTP frame for data 222 ); 223 224 /**Call back to handle received media data. 225 If false is returned then OnWriteMediaData() is called. 226 227 Care with the handling of real time is rqeuired, see GetSynchronicity 228 for more details. 229 230 The default implementation returns false. 231 */ 232 virtual bool OnWriteMediaFrame( 233 const OpalLocalConnection & connection, ///< Connection for media 234 const OpalMediaStream & mediaStream, ///< Media stream data is required for 235 RTP_DataFrame & frame ///< RTP frame for data 236 ); 237 238 /**Call back to get media data for transmission. 239 If false is returned the media stream will be closed. 240 241 Care with the handling of real time is rqeuired, see GetSynchronicity 242 for more details. 243 244 The default implementation returns false. 245 */ 246 virtual bool OnReadMediaData( 247 const OpalLocalConnection & connection, ///< Connection for media 248 const OpalMediaStream & mediaStream, ///< Media stream data is required for 249 void * data, ///< Data to send 250 PINDEX size, ///< Maximum size of data buffer 251 PINDEX & length ///< Number of bytes placed in buffer 252 ); 253 254 /**Call back to handle received media data. 255 If false is returned the media stream will be closed. 256 257 Care with the handling of real time is rqeuired, see GetSynchronicity 258 for more details. 259 260 The default implementation returns false. 261 */ 262 virtual bool OnWriteMediaData( 263 const OpalLocalConnection & connection, ///< Connection for media 264 const OpalMediaStream & mediaStream, ///< Media stream data is required for 265 const void * data, ///< Data received 266 PINDEX length, ///< Amount of data available to write 267 PINDEX & written ///< Amount of data written 268 ); 269 270 /**Indicate the synchronous mode for I/O. 271 This indicates that the OnReadMediaXXX and OnWriteMediaXXX functions 272 will execute blocking to the correct real time synchronisation. 273 If GetSynchronicity() returns e_Synchronous, then, for example, when 274 OnWriteMediaData() is sent 320 bytes of PCM data, it will block for 275 20 milliseconds. 276 277 If GetSynchronicity() returns e_SimulateSyncronous, then the system will try and 278 simulate the correct timing using the operating system sleep function. 279 This is not desirable as this function is notoriously inaccurate, and 280 OPAL does it's best to compensate, but very often there is no other 281 choice. 282 283 Note, it is important for the correct oeprating of the jitter buffer 284 that one of the above two modes is used for audio. 285 286 If GetSynchronicity() returns e_Asynchronous, then the system will indicate 287 that blocking is not required in any way. For example, when playing video, 288 this is done as fast as data comes in from the network and there is no 289 real time pacing required. 290 */ 291 enum Synchronicity { 292 e_Synchronous, ///< Functions will block for correct real time 293 e_Asynchronous, ///< Functions will not block, and do not require any real time handling. 294 e_SimulateSyncronous ///< Functions wlll not block, but do require real time handling. 295 }; 296 297 /**Indicate the I/O synchronous mode. 298 See Synchronicity for more details. 299 300 Default behaviour returns m_defaultAudioSynchronicity (initially 301 e_Synchronous) when is audio source or sink, 302 m_defaultVideoSourceSynchronicity (initially e_Synchronous) when a 303 video source, e_Asynchronous in all other cases. 304 */ 305 virtual Synchronicity GetSynchronicity( 306 const OpalMediaFormat & mediaFormat, ///< Media format for stream being opened. 307 bool isSource ///< Stream is a a source 308 ) const; 309 310 /**Get default synchronous mode for audio sources and sinks. 311 */ GetDefaultAudioSynchronicity()312 Synchronicity GetDefaultAudioSynchronicity() const { return m_defaultAudioSynchronicity; } 313 314 /**Set default synchronous mode for audio sources and sinks. 315 */ SetDefaultAudioSynchronicity(Synchronicity sync)316 void SetDefaultAudioSynchronicity(Synchronicity sync) { m_defaultAudioSynchronicity = sync; } 317 318 /**Get default synchronous mode for video sources. 319 */ GetDefaultVideoSourceSynchronicity()320 Synchronicity GetDefaultVideoSourceSynchronicity() const { return m_defaultVideoSourceSynchronicity; } 321 322 /**Set default synchronous mode for video sources. 323 */ SetDefaultVideoSourceSynchronicity(Synchronicity sync)324 void SetDefaultVideoSourceSynchronicity(Synchronicity sync) { m_defaultVideoSourceSynchronicity = sync; } 325 326 /**Indicate OnAlerting() is be deferred or immediate. 327 */ IsDeferredAlerting()328 bool IsDeferredAlerting() const { return m_deferredAlerting; } 329 330 /**Indicate OnAlerting() is be deferred or immediate. 331 */ SetDeferredAlerting(bool defer)332 void SetDeferredAlerting(bool defer) { m_deferredAlerting = defer; } 333 334 /**Indicate AcceptIncomingCall() execution is be deferred or immediate on OnIncomingCall(). 335 */ IsDeferredAnswer()336 bool IsDeferredAnswer() const { return m_deferredAnswer; } 337 338 /**Indicate AcceptIncomingCall() execution is be deferred or immediate on OnIncomingCall(). 339 */ SetDeferredAnswer(bool defer)340 void SetDeferredAnswer(bool defer) { m_deferredAnswer = defer; } 341 //@} 342 343 protected: 344 bool m_deferredAlerting; 345 bool m_deferredAnswer; 346 347 Synchronicity m_defaultAudioSynchronicity; 348 Synchronicity m_defaultVideoSourceSynchronicity; 349 350 private: 351 P_REMOVE_VIRTUAL(OpalLocalConnection *, CreateConnection(OpalCall &, void *), 0); 352 P_REMOVE_VIRTUAL(bool, IsSynchronous() const, false); 353 }; 354 355 356 /** Local connection. 357 This class represents a connection on the local machine that can receive 358 media via virtual functions. 359 */ 360 class OpalLocalConnection : public OpalConnection 361 { 362 PCLASSINFO(OpalLocalConnection, OpalConnection); 363 public: 364 /**@name Construction */ 365 //@{ 366 /**Create a new connection. 367 */ 368 OpalLocalConnection( 369 OpalCall & call, ///< Owner call for connection 370 OpalLocalEndPoint & endpoint, ///< Owner endpoint for connection 371 void * userData, ///< Arbitrary data to pass to connection 372 unsigned options, ///< Option bit mask to pass to connection 373 OpalConnection::StringOptions * stringOptions, ///< Options to pass to connection 374 char tokenPrefix = 'L' ///< Prefix for token generation 375 ); 376 377 /**Destroy connection. 378 */ 379 ~OpalLocalConnection(); 380 //@} 381 382 /**@name Overrides from OpalConnection */ 383 //@{ 384 /**Get indication of connection being to a "network". 385 This indicates the if the connection may be regarded as a "network" 386 connection. The distinction is about if there is a concept of a "remote" 387 party being connected to and is best described by example: sip, h323, 388 iax and pstn are all "network" connections as they connect to something 389 "remote". While pc, pots and ivr are not as the entity being connected 390 to is intrinsically local. 391 */ IsNetworkConnection()392 virtual PBoolean IsNetworkConnection() const { return false; } 393 394 /// Call back for connection to act on changed string options 395 virtual void OnApplyStringOptions(); 396 397 /**Start an outgoing connection. 398 This function will initiate the connection to the remote entity, for 399 example in H.323 it sends a SETUP, in SIP it sends an INVITE etc. 400 401 The default behaviour determines if this si incoming or outgoing call 402 by checking if we are party A or B, then does approriate setting up 403 of the conenction, including calling OnOutgoing() or OnIncoming() as 404 appropriate. 405 */ 406 virtual PBoolean SetUpConnection(); 407 408 /**Indicate to remote endpoint an alert is in progress. 409 If this is an incoming connection and the AnswerCallResponse is in a 410 AnswerCallDeferred or AnswerCallPending state, then this function is 411 used to indicate to that endpoint that an alert is in progress. This is 412 usually due to another connection which is in the call (the B party) 413 has received an OnAlerting() indicating that its remote endpoint is 414 "ringing". 415 416 The default behaviour does nothing. 417 */ 418 virtual PBoolean SetAlerting( 419 const PString & calleeName, ///< Name of endpoint being alerted. 420 PBoolean withMedia ///< Open media with alerting 421 ); 422 423 /**Indicate to remote endpoint we are connected. 424 425 The default behaviour sets the phase to ConnectedPhase, sets the 426 connection start time and then checks if there is any media channels 427 opened and if so, moves on to the established phase, calling 428 OnEstablished(). 429 430 In other words, this method is used to handle incoming calls, 431 and is an indication that we have accepted the incoming call. 432 */ 433 virtual PBoolean SetConnected(); 434 435 /**Open a new media stream. 436 This will create a media stream of an appropriate subclass as required 437 by the underlying connection protocol. For instance H.323 would create 438 an OpalRTPStream. 439 440 The sessionID parameter may not be needed by a particular media stream 441 and may be ignored. In the case of an OpalRTPStream it us used. 442 443 Note that media streams may be created internally to the underlying 444 protocol. This function is not the only way a stream can come into 445 existance. 446 447 The default behaviour is pure. 448 */ 449 virtual OpalMediaStream * CreateMediaStream( 450 const OpalMediaFormat & mediaFormat, ///< Media format for stream 451 unsigned sessionID, ///< Session number for stream 452 PBoolean isSource ///< Is a source stream 453 ); 454 455 /**Open source or sink media stream for session. 456 */ 457 virtual OpalMediaStreamPtr OpenMediaStream( 458 const OpalMediaFormat & mediaFormat, ///< Media format to open 459 unsigned sessionID, ///< Session to start stream on 460 bool isSource ///< Stream is a source/sink 461 ); 462 463 /**Send a user input indication to the remote endpoint. 464 This sends an arbitrary string as a user indication. If DTMF tones in 465 particular are required to be sent then the SendIndicationTone() 466 function should be used. 467 468 The default behaviour plays the DTMF tones on the line. 469 */ 470 virtual PBoolean SendUserInputString( 471 const PString & value ///< String value of indication 472 ); 473 //@} 474 475 /**@name New operations */ 476 //@{ 477 /**Call back just before remote is contacted. 478 479 The default implementation call OpalLocalEndPoint::OnOutgoingSetUp(). 480 481 @return false if the call is to be aborted with EndedByNoAccept. 482 */ 483 virtual bool OnOutgoingSetUp(); 484 485 /**Call back to indicate that remote is ringing. 486 487 The default implementation call OpalLocalEndPoint::OnOutgoingCall(). 488 489 @return false if the call is to be aborted with EndedByNoAccept. 490 */ 491 virtual bool OnOutgoing(); 492 493 /**Call back to indicate that there is an incoming call. 494 Note this function should not block or it will impede the operation of 495 the stack. 496 497 The default implementation call OpalLocalEndPoint::OnIncomingCall(). 498 499 @return false if the call is to be aborted with status of EndedByLocalBusy. 500 */ 501 virtual bool OnIncoming(); 502 503 /**Indicate alerting for the incoming connection. 504 */ 505 virtual void AlertingIncoming(); 506 507 /**Accept the incoming connection. 508 */ 509 virtual void AcceptIncoming(); 510 //@} 511 512 /**@name Member variable access */ 513 //@{ 514 /// Get user data pointer. GetUserData()515 void * GetUserData() const { return m_userData; } 516 517 /// Set user data pointer. SetUserData(void * v)518 void SetUserData(void * v) { m_userData = v; } 519 //@} 520 521 protected: 522 OpalLocalEndPoint & endpoint; 523 void * m_userData; 524 }; 525 526 527 /**Local media stream. 528 This class represents a media stream on the local machine that can receive 529 media via virtual functions. 530 */ 531 class OpalLocalMediaStream : public OpalMediaStream, public OpalMediaStreamPacing 532 { 533 PCLASSINFO(OpalLocalMediaStream, OpalMediaStream); 534 public: 535 /**@name Construction */ 536 //@{ 537 /**Construct a new media stream for local system. 538 */ 539 OpalLocalMediaStream( 540 OpalLocalConnection & conn, ///< Connection for media stream 541 const OpalMediaFormat & mediaFormat, ///< Media format for stream 542 unsigned sessionID, ///< Session number for stream 543 bool isSource, ///< Is a source stream 544 OpalLocalEndPoint::Synchronicity synchronicity ///< Synchronous mode 545 ); 546 //@} 547 548 /**@name Overrides of OpalMediaStream class */ 549 //@{ 550 /**Read an RTP frame of data from the source media stream. 551 The default behaviour simply calls ReadData() on the data portion of the 552 RTP_DataFrame and sets the frames timestamp and marker from the internal 553 member variables of the media stream class. 554 */ 555 virtual PBoolean ReadPacket( 556 RTP_DataFrame & packet 557 ); 558 559 /**Write an RTP frame of data to the sink media stream. 560 The default behaviour simply calls WriteData() on the data portion of the 561 RTP_DataFrame and and sets the internal timestamp and marker from the 562 member variables of the media stream class. 563 */ 564 virtual PBoolean WritePacket( 565 RTP_DataFrame & packet 566 ); 567 568 /**Read raw media data from the source media stream. 569 The default behaviour reads from the OpalLine object. 570 */ 571 virtual PBoolean ReadData( 572 BYTE * data, ///< Data buffer to read to 573 PINDEX size, ///< Size of buffer 574 PINDEX & length ///< Length of data actually read 575 ); 576 577 /**Write raw media data to the sink media stream. 578 The default behaviour writes to the OpalLine object. 579 */ 580 virtual PBoolean WriteData( 581 const BYTE * data, ///< Data to write 582 PINDEX length, ///< Length of data to read. 583 PINDEX & written ///< Length of data actually written 584 ); 585 586 /**Indicate if the media stream is synchronous. 587 Returns true for LID streams. 588 */ 589 virtual PBoolean IsSynchronous() const; 590 //@} 591 592 protected: InternalClose()593 virtual void InternalClose() { } 594 595 OpalLocalEndPoint::Synchronicity m_synchronicity; 596 }; 597 598 599 #endif // OPAL_OPAL_LOCALEP_H 600 601 602 // End of File /////////////////////////////////////////////////////////////// 603