1 /* 2 * call.h 3 * 4 * Telephone call management 5 * 6 * Open Phone Abstraction Library (OPAL) 7 * Formally known as the Open H323 project. 8 * 9 * Copyright (c) 2001 Equivalence 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: 28690 $ 28 * $Author: rjongbloed $ 29 * $Date: 2012-12-18 20:47:15 -0600 (Tue, 18 Dec 2012) $ 30 */ 31 32 #ifndef OPAL_OPAL_CALL_H 33 #define OPAL_OPAL_CALL_H 34 35 #ifdef P_USE_PRAGMA 36 #pragma interface 37 #endif 38 39 #include <opal/buildopts.h> 40 41 #include <opal/connection.h> 42 #include <opal/recording.h> 43 #include <opal/guid.h> 44 45 #include <ptlib/safecoll.h> 46 47 48 class OpalManager; 49 50 51 /**This class manages a call. 52 A call consists of one or more OpalConnection instances. While these 53 connections may be created elsewhere this class is responsible for their 54 disposal. 55 56 An OpalCall could manage (for example) a H323Connection and 57 PCSSConnection instance, which allows the user to use opal in a 58 H.323 application. Alternatively, if OpalCall manages a 59 H323Connection and a SIPConnection instance, the call is being 60 gatewayed from one protocol to another. 61 62 In a conference situation, one OpalCall would manage lots of 63 H323Connection/SIPConnection classes. 64 */ 65 class OpalCall : public PSafeObject 66 { 67 PCLASSINFO(OpalCall, PSafeObject); 68 public: 69 /**@name Construction */ 70 //@{ 71 /**Create a new call. 72 */ 73 OpalCall( 74 OpalManager & manager ///< Manager for the opal system 75 ); 76 77 /**Destroy call. 78 */ 79 ~OpalCall(); 80 //@} 81 82 /**@name Overrides from PObject */ 83 //@{ 84 /**Standard stream print function. 85 The PObject class has a << operator defined that calls this function 86 polymorphically. 87 */ 88 void PrintOn( 89 ostream & strm ///< Stream to output text representation 90 ) const; 91 //@} 92 93 /**@name Basic operations */ 94 //@{ 95 /**Indicate tha all connections in call are connected and media is going. 96 */ IsEstablished()97 PBoolean IsEstablished() const { return isEstablished; } 98 99 /**Call back to indicate that the call has been established. 100 At this point in time every connection in the call is in the 101 "Established" state. This is a better function than using 102 OnEstablished() on a particular connection as it assures that 103 bi-direction media is flowing. 104 105 The default behaviour is to call OpalManager::OnEstablishedCall(). 106 */ 107 virtual void OnEstablishedCall(); 108 109 /**Get the call clearand reason for this connection shutting down. 110 Note that this function is only generally useful in the 111 OpalEndPoint::OnClearedCall() function. This is due to the 112 connection not being cleared before that, and the object not even 113 existing after that. 114 115 If the call is still active then this will return OpalConnection::NumCallEndReasons. 116 */ GetCallEndReason()117 OpalConnection::CallEndReason GetCallEndReason() const { return callEndReason; } 118 119 /**Get the reason for this connection shutting down as text. 120 */ GetCallEndReasonText()121 PString GetCallEndReasonText() const { return OpalConnection::GetCallEndReasonText(callEndReason); } 122 123 /**Set the call clearance reason. 124 An application should have no cause to use this function. It is present 125 for the H323EndPoint::ClearCall() function to set the clearance reason. 126 */ 127 void SetCallEndReason( 128 OpalConnection::CallEndReason reason ///< Reason for clearance of connection. 129 ); 130 131 /**Clear call. 132 This releases all connections currently attached to the call. Note that 133 this function will return quickly as the release and disposal of the 134 connections is done by another thread. 135 136 The sync parameter is a PSyncPoint that will be signalled during the 137 destructor for the OpalCall. Note only one thread may do this at a time. 138 */ 139 void Clear( 140 OpalConnection::CallEndReason reason = OpalConnection::EndedByLocalUser, ///< Reason for call clearing 141 PSyncPoint * sync = NULL ///< Sync point to signal on call destruction 142 ); 143 144 /**Call back to indicate that the call has been cleared. 145 At this point in time there are no connections left in the call. 146 147 The default behaviour is to call OpalManager::OnClearedCall(). 148 */ 149 virtual void OnCleared(); 150 //@} 151 152 /**@name Connection management */ 153 //@{ 154 /**Call back for a new connection has been constructed. 155 This is called after CreateConnection has returned a new connection. 156 It allows an application to make any custom adjustments to the 157 connection before it begins to process the protocol. behind it. 158 */ 159 virtual void OnNewConnection( 160 OpalConnection & connection ///< New connection just created 161 ); 162 163 /**Call back for SetUp conenction. 164 165 The default behaviour is to call SetUpConnection() on all the other 166 connections in the call. 167 */ 168 virtual PBoolean OnSetUp( 169 OpalConnection & connection ///< Connection that indicates it is alerting 170 ); 171 172 /**Call back for remote party is now responsible for completing the call. 173 This function is called when the remote system has been contacted and it 174 has accepted responsibility for completing, or failing, the call. This 175 is distinct from OnAlerting() in that it is not known at this time if 176 anything is ringing. This indication may be used to distinguish between 177 "transport" level error, in which case another host may be tried, and 178 that finalising the call has moved "upstream" and the local system has 179 no more to do but await a result. 180 181 If an application overrides this function, it should generally call the 182 ancestor version for correct operation. 183 184 The default behaviour does nothing. 185 */ 186 virtual void OnProceeding( 187 OpalConnection & connection ///< Connection that is proceeeding 188 ); 189 190 /**Call back for remote party being alerted. 191 This function is called after the connection is informed that the 192 remote endpoint is "ringing". Generally some time after the 193 MakeConnection() function was called, this is function is called. 194 195 If false is returned the connection is aborted. 196 197 If an application overrides this function, it should generally call the 198 ancestor version for correct operation. An application would typically 199 only intercept this function if it wishes to do some form of logging. 200 For this you can obtain the name of the caller by using the function 201 OpalConnection::GetRemotePartyName(). 202 203 The default behaviour is to call SetAlerting() on all the other 204 connections in the call. 205 */ 206 virtual PBoolean OnAlerting( 207 OpalConnection & connection ///< Connection that indicates it is alerting 208 ); 209 210 /**Call back for answering an incoming call. 211 This function is called after the connection has been acknowledged 212 but before the connection is established 213 214 This gives the application time to wait for some event before 215 signalling to the endpoint that the connection is to proceed. For 216 example the user pressing an "Answer call" button. 217 218 If AnswerCallDenied is returned the connection is aborted and the 219 connetion specific end call PDU is sent. If AnswerCallNow is returned 220 then the connection proceeding, Finally if AnswerCallPending is returned then the 221 protocol negotiations are paused until the AnsweringCall() function is 222 called. 223 224 The default behaviour returns AnswerCallPending. 225 */ 226 virtual OpalConnection::AnswerCallResponse OnAnswerCall( 227 OpalConnection & connection, 228 const PString & caller 229 ); 230 231 /**A call back function whenever a connection is "connected". 232 This indicates that a connection to an endpoint was connected. That 233 is the endpoint received acknowledgement via whatever protocol it uses 234 that the connection may now start media streams. 235 236 In the context of H.323 this means that the CONNECT pdu has been 237 received. 238 239 The default behaviour is to call SetConnected() on all other 240 connections in the call. 241 */ 242 virtual PBoolean OnConnected( 243 OpalConnection & connection ///< Connection that indicates it is alerting 244 ); 245 246 /**A call back function whenever a connection is "established". 247 This indicates that a connection to an endpoint was established. This 248 usually occurs after OnConnected() and indicates that the connection 249 is both connected and has media flowing. 250 251 In the context of H.323 this means that the CONNECT pdu has been 252 received and either fast start was in operation or the subsequent Open 253 Logical Channels have occurred. For SIP it indicates the INVITE/OK/ACK 254 sequence is complete. 255 256 The default behaviour is to check that all connections in call are 257 established and if so, marks the call as established and calls 258 OnEstablishedCall(). 259 */ 260 virtual PBoolean OnEstablished( 261 OpalConnection & connection ///< Connection that indicates it is alerting 262 ); 263 264 /**A call back function whenever a connection is released. 265 266 The default behaviour releases the remaining connection if there is 267 only one left. 268 */ 269 virtual void OnReleased( 270 OpalConnection & connection ///< Connection that was established 271 ); 272 273 /**A call back function whenever a connection is "held" or "retrieved". 274 This indicates that a connection of a call was held, or 275 retrieved, either locally or by the remote endpoint. 276 277 The default behaviour does nothing. 278 */ 279 virtual void OnHold( 280 OpalConnection & connection, ///< Connection that was held/retrieved 281 bool fromRemote, ///< Indicates remote has held local connection 282 bool onHold ///< Indicates have just been held/retrieved. 283 ); 284 285 /**Get the other party's connection object. 286 This will return the other party in the call. It will return NULL if 287 there is no other party yet, or there are more than two parties in the 288 call. Usefull during certain stages during initial call set up. 289 */ 290 PSafePtr<OpalConnection> GetOtherPartyConnection( 291 const OpalConnection & connection ///< Source requesting formats 292 ) const; 293 294 /**Get the specified active connection in call. 295 */ 296 PSafePtr<OpalConnection> GetConnection( 297 PINDEX idx, 298 PSafetyMode mode = PSafeReference 299 ) { return connectionsActive.GetAt(idx, mode); } 300 301 /**Find a connection of the specified class. 302 This searches the call for the Nth connection of the specified class. 303 */ 304 template <class ConnClass> 305 PSafePtr<ConnClass> GetConnectionAs( 306 PINDEX count = 0, 307 PSafetyMode mode = PSafeReadWrite 308 ) 309 { 310 PSafePtr<ConnClass> connection; 311 for (PSafePtr<OpalConnection> iterConn(connectionsActive, PSafeReference); iterConn != NULL; ++iterConn) { 312 if ((connection = PSafePtrCast<OpalConnection, ConnClass>(iterConn)) != NULL && count-- == 0) { 313 if (!connection.SetSafetyMode(mode)) 314 connection.SetNULL(); 315 break; 316 } 317 } 318 return connection; 319 } 320 321 /**Put call on hold. 322 This function places the remote user of the network connection in the 323 call on hold. 324 */ 325 bool Hold(); 326 327 /**Retrieve call from hold. 328 This function retrieves the remote user of the network connection in 329 the call from hold. 330 */ 331 bool Retrieve(); 332 333 /**Indicate if call is in hold. 334 This function determines if the remote user of the network connection 335 in the call is currently on hold. 336 */ 337 bool IsOnHold() const; 338 339 /**Transfer connection. 340 There are several scenarios for this function. 341 342 If 'connection' is not NULL and the protocol type for 'address' is 343 the same, or the protocol type is "*", or the address is a valid and 344 current call token, then this simply calls TransferConnection() on the 345 'connection' variable. 346 347 e.g. connection="sip:fred@bloggs.com" and address="*:1234", then 348 connection->TransferConnection("sip:1234") is called, which sends a 349 REFER command to the remote. The connection and call are subsequently 350 released in this case. 351 352 Another example, if connection="pc:Speakers" and address="pc:Headset", 353 then the sound device in the 'connection' instance is changed and the 354 call and media is continued unchanged. The connection and call are 355 <b>not</b> released in this case. 356 357 If there is a protocol change, e.g. "pc:" to "t38:", then 'connection' 358 is completely released, all media streams to the second conection in 359 the call (if any) are severed and a new connection established and new 360 media streams started. 361 362 If 'connection' is NULL, it will choose the first connection in the call 363 of the same protocol type. For example, in the previous example above 364 where address="pc:Headset", and the call is from "pc:Speakers" to 365 "sip:fred@bloggs.com", the function would operate the same even if 366 'connection' is NULL. 367 368 If there are no connections of the same protocol type, then nothing is 369 done and false is returned. 370 */ 371 bool Transfer( 372 const PString & address, ///< New address to transfer to 373 OpalConnection * connection = NULL ///< Connection to transfer 374 ); 375 //@} 376 377 /**@name Media management */ 378 //@{ 379 /**Get the media formats of the connections in call. 380 This returns the intersection of all the media formats available in 381 connections in the call, not including the parameter. It is in 382 esence the "local" media formats available to the connection. 383 384 This will also add to the list all media formats for which there are 385 transcoders registered. 386 */ 387 virtual OpalMediaFormatList GetMediaFormats( 388 const OpalConnection & connection ///< Connection requesting formats 389 ); 390 391 /**Adjust media formats available on a connection. 392 This is called by a connection after it has called 393 OpalCall::GetMediaFormats() to get all media formats that it can use so 394 that an application may remove or reorder the media formats before they 395 are used to open media streams. 396 397 The default behaviour calls the OpalManager function of the same name. 398 */ 399 virtual void AdjustMediaFormats( 400 bool local, ///< Media formats a local ones to be presented to remote 401 const OpalConnection & connection, ///< Connection that is about to use formats 402 OpalMediaFormatList & mediaFormats ///< Media formats to use 403 ) const; 404 405 /**Open source media streams for the specified connection. 406 A source media stream is opened for the connection, if successful then 407 sink media streams are created for every other connection in the call. 408 If at least one sink is created then an OpalMediaPatch is created to 409 transfer data from the source to the sinks. 410 411 If session ID is zero a new session is created. If session ID is non 412 zero then that existing session is replaced. 413 */ 414 virtual bool OpenSourceMediaStreams( 415 OpalConnection & connection, ///< Connection requesting open 416 const OpalMediaType & mediaType, ///< Media type of channel to open 417 unsigned sessionID = 0, ///< Session to start streams on 418 const OpalMediaFormat & preselectedFormat = OpalMediaFormat() ///< Format for source stream to choose from 419 #if OPAL_VIDEO 420 , OpalVideoFormat::ContentRole contentRole = OpalVideoFormat::eNoRole ///< Content role for video 421 #endif 422 ); 423 424 /**Select media format pair from the source/destination list. 425 426 Default behavour calls OpalTranscoder::SelectFormats(). 427 */ 428 virtual bool SelectMediaFormats( 429 const OpalMediaType & mediaType, ///< Media type for selection. 430 const OpalMediaFormatList & srcFormats, ///< Names of possible source formats 431 const OpalMediaFormatList & dstFormats, ///< Names of possible destination formats 432 const OpalMediaFormatList & allFormats, ///< Master list of formats for merging options 433 OpalMediaFormat & srcFormat, ///< Selected source format to be used 434 OpalMediaFormat & dstFormat ///< Selected destination format to be used 435 ) const; 436 437 /**Callback from the RTP session for statistics monitoring. 438 This is called every so many packets on the transmitter and receiver 439 threads of the RTP session indicating that the statistics have been 440 updated. 441 442 The default behaviour does nothing. 443 */ 444 virtual void OnRTPStatistics( 445 const OpalConnection & connection, ///< Connection for the channel 446 const RTP_Session & session ///< Session with statistics 447 ); 448 449 /**Start the media streams on the connections. 450 */ 451 virtual void StartMediaStreams(); 452 453 /**Close the media streams on the connections. 454 */ 455 virtual void CloseMediaStreams(); 456 457 /**See if the media can bypass the local host. 458 */ 459 virtual PBoolean IsMediaBypassPossible( 460 const OpalConnection & connection, ///< Source connection 461 unsigned sessionID ///< Session ID for media channel 462 ) const; 463 //@} 464 465 /**@name User indications */ 466 //@{ 467 /**Call back for remote endpoint has sent user input as a string. 468 469 The default behaviour call OpalConnection::SetUserInput() which 470 saves the value so the GetUserInput() function can return it. 471 */ 472 virtual void OnUserInputString( 473 OpalConnection & connection, ///< Connection input has come from 474 const PString & value ///< String value of indication 475 ); 476 477 /**Call back for remote enpoint has sent user input as tones. 478 If duration is zero then this indicates the beginning of the tone. If 479 duration is non-zero then it indicates the end of the tone output. 480 481 The default behaviour calls connection.OnUserInputString(tone) if there 482 are no other connections in the call, otherwise it calls 483 SendUserInputTone() for each of the other connections in the call. 484 */ 485 virtual void OnUserInputTone( 486 OpalConnection & connection, ///< Connection input has come from 487 char tone, ///< Tone received 488 int duration ///< Duration of tone in milliseconds 489 ); 490 //@} 491 492 /**@name Member variable access */ 493 //@{ 494 /**Get the manager for this endpoint. 495 */ GetManager()496 OpalManager & GetManager() const { return manager; } 497 498 /**Get the internal identifier token for this connection. 499 */ GetToken()500 const PString & GetToken() const { return myToken; } 501 502 /**Get the A party for the call. 503 Note this will be available even after the A party connection has been 504 released from the call. 505 */ GetPartyA()506 const PString & GetPartyA() const { return m_partyA; } 507 508 /**Get the B party for the call. 509 Note this will be available even after the B party connection has been 510 released from the call. Also this will only be the first B party if the 511 object represents a conference call with more that 2 parties. 512 */ GetPartyB()513 const PString & GetPartyB() const { return m_partyB; } 514 515 /**Set the B party for a call. 516 This is used when we wish to make two outgoing calls and bridge them. 517 When the OnConnected() call back occurs for the first outgoing call 518 (the A-Party) then this variable ised to make teh second outgoing call. 519 */ SetPartyB(const PString & b)520 void SetPartyB( 521 const PString & b 522 ) { m_partyB = b; } 523 524 /**Get indication that A-Party is the network. 525 This will indicate if the call is "incoming" or "outgoing" by looking at 526 the type of the A-party connection. 527 */ 528 bool IsNetworkOriginated() const; 529 530 /**Get the time the call started. 531 */ GetStartTime()532 const PTime & GetStartTime() const { return startTime; } 533 //@} 534 535 #if OPAL_HAS_MIXER 536 /**Start recording a call. 537 Current version saves to a WAV file. It may either mix the receive and 538 transmit audio stream to a single mono file, or the streams are placed 539 into the left and right channels of a stereo WAV file. 540 */ 541 bool StartRecording( 542 const PFilePath & filename, ///< File into which to record 543 const OpalRecordManager::Options & options = false ///< Record mixing options 544 ); 545 546 /**Indicate if recording is currently active on call. 547 */ 548 bool IsRecording() const; 549 550 /** Stop a recording. 551 Returns true if the call does exists, an active call is not indicated. 552 */ 553 void StopRecording(); 554 555 /** Call back on recording started. 556 */ 557 virtual bool OnStartRecording( 558 const PString & streamId, ///< Unique ID for stream within call 559 const OpalMediaFormat & format ///< Media format for stream 560 ); 561 562 /** Call back on recording stopped. 563 */ 564 virtual void OnStopRecording( 565 const PString & streamId ///< Unique ID for stream within call 566 ); 567 568 /** Call back for having a frame of audio to record. 569 */ 570 virtual void OnRecordAudio( 571 const PString & streamId, ///< Unique ID for stream within call 572 const RTP_DataFrame & frame ///< Media data 573 ); 574 575 #if OPAL_VIDEO 576 /** Call back for having a frame of video to record. 577 */ 578 virtual void OnRecordVideo( 579 const PString & streamId, ///< Unique ID for stream within call 580 const RTP_DataFrame & frame ///< Media data 581 ); 582 #endif 583 #endif // OPAL_HAS_MIXER 584 585 void InternalOnClear(); 586 587 void SetPartyNames(); 588 589 protected: 590 bool EnumerateConnections( 591 PSafePtr<OpalConnection> & connection, 592 PSafetyMode mode, 593 const OpalConnection * skipConnection = NULL 594 ) const; 595 596 OpalManager & manager; 597 598 PString myToken; 599 600 PString m_partyA; 601 PString m_partyB; 602 PTime startTime; 603 bool isEstablished; 604 bool isClearing; 605 PAtomicBoolean m_isCleared; 606 607 OpalConnection::CallEndReason callEndReason; 608 std::list<PSyncPoint *> m_endCallSyncPoint; 609 610 PSafeList<OpalConnection> connectionsActive; 611 612 #if OPAL_HAS_MIXER 613 OpalRecordManager * m_recordManager; 614 #endif 615 616 //use to add the connection to the call's connection list 617 friend OpalConnection::OpalConnection(OpalCall &, OpalEndPoint &, const PString &, unsigned int, OpalConnection::StringOptions *); 618 //use to remove the connection from the call's connection list 619 friend OpalConnection::~OpalConnection(); 620 }; 621 622 623 #endif // OPAL_OPAL_CALL_H 624 625 626 // End of File /////////////////////////////////////////////////////////////// 627