CAF: Working With Caf Call Legs
(→Constructing leg attributes) |
(→Destruction the CTBCAFCallFlow object and it's legs) |
||
Line 199: | Line 199: | ||
== Destruction the ''CTBCAFCallFlow'' object and it's legs == | == Destruction the ''CTBCAFCallFlow'' object and it's legs == | ||
+ | === Self-destructing call legs, behaviors, and call flow === | ||
The ''CTBCAFCallFlow'' object contains smart pointers to it's call legs. Destruction of these call legs will thus occur when removing the last smart pointer reference to the pointed call leg object. | The ''CTBCAFCallFlow'' object contains smart pointers to it's call legs. Destruction of these call legs will thus occur when removing the last smart pointer reference to the pointed call leg object. | ||
Line 204: | Line 205: | ||
Also upon destruction of the last call leg, object based on ''CTBCAFCallFlow'' or ''CTBCAFCallBehavior'' will delete themselves automatically, by calling the attached "free listener" (that was provided in the constructor of the call flow object). | Also upon destruction of the last call leg, object based on ''CTBCAFCallFlow'' or ''CTBCAFCallBehavior'' will delete themselves automatically, by calling the attached "free listener" (that was provided in the constructor of the call flow object). | ||
+ | |||
+ | === Call termination callbacks and actions === | ||
+ | ==== ''OnCallLegTerminatingIndication()'' ==== | ||
+ | This callback means that toolpack_engine has received a termination request from a call leg (SIP Bye, ISUP REL, for example). | ||
+ | A typical use of that event is to call TerminateCall() on both incoming and outgoing legs of a call flow, to hangup both sides. | ||
+ | |||
+ | ==== ''TerminateCall()'' ==== | ||
+ | It is MANDATORY that this function is called for each call leg before the leg can be destroyed. It's used to confirm to toolpack_engine that the CAF application has terminated with the call leg, and that the signaling can properly be terminated. | ||
+ | |||
+ | It's up to the application, however, to call the function immediately (within ''OnCallLegTerminatingIndication()'' for example) or later after doing some more job (like asynchronous database updates, for example) | ||
+ | |||
+ | ==== ''OnCallLegTerminated()'' ==== | ||
+ | This callback confirms that toolpack_engine has finished closing the data path and signaling for this call leg. It's the last event that should be received on a call leg (outside ''OnLegFreed()'', of course). | ||
+ | |||
+ | ==== ''FreeLeg()'' ==== | ||
+ | It is MANDATORY that this function is called for each call leg after OnCallLegTerminated(). | ||
+ | |||
+ | It's up to the application, however, to call the function immediately (within ''OnCallLegTerminated()'' for example) or later after doing some more job (like asynchronous database updates, for example) | ||
+ | |||
+ | ==== ''OnLegFreed()'' ==== | ||
+ | This callback confirms that the leg is being freed. | ||
+ | |||
+ | It's the last chance for a call flow or a behavior to release things related to a call leg, like canceling timers for example. | ||
+ | |||
+ | The base classes CTBCAFCallBehavior and CTBCAFCallFlow | ||
+ | |||
+ | *'''Important note:''' Behaviors that implement that function MUST, as the LAST line of their function, call the base class' ''CTBCAFCallBehavior::OnLegFreed''. Not calling base class' function will cause the call to leak. Calling that before the last line of the function will cause crash, as the Behavior object will destroy itself within that function upon destruction of the last leg of the call. |
Revision as of 13:33, 7 April 2011
Contents |
Overview
CAF Call leg (CTBCAFCallLeg):
The CTBCAFCallLeg is the representation of communication with one peer, through one protocol (SS7, ISDN, SIP, CAS).
They can be created either after the toolpack_engine has notified the CAF application that a new call has been received, or else when the CAF application asks toolpack_engine to create a new outgoing call. When creating a new outgoing call, attributes are provided to indicate toolpack_engine which NAP to make the call to (which also defines the signaling protocol), which calling/called numbers to use, etc.
From the C++ point of view, the CTBCAFCallLeg class is a wrapper around the CTBCMCLeg object. It's enhancing the CTBCMCLeg object so multiple call legs can be grouped and managed together from a parent Call object (CTBCAFCallFlow).
CAF Call Flow (CTBCAFCallFlow):
The CTBCAFCallFlow base class contains one or multiple CTBCAFCallLeg objects. The role of the CTBCAFCallFlow object is to implement a call flow that involves actions on legs that have a relation with each other.
CAF Call Bridge (CTBCAFBridge, based on CTBCAFCallFlow):
A typical implementation of a call flow is the CTBCAFBridge class (based on the CTBCAFCallFlow base class). This class is designed to - Receive an incoming call - Make a corresponding outgoing call - Join them together - Terminate both of them when one leg hangups.
CAF Call Behavior (CTBCAFCallBehavior):
Behaviors CTBCAFCallBehavior can be attached to a call flow (CTBCAFCallFlow). Their role is to modify the basic call flow, decorating it with optional functionality (CDR logging, FAX detection, Ring tone playback, etc.)
Actions on call legs
The call flow can perform various actions on each of it's call legs. Here is a list of the actions available on the CTBCAFCallLeg objects (please refer to the header files CTBCMCLeg.hpp for more information on each of these functions).
Controlling call flow:
- AcceptCall() - AlertCall() - AnswerCall() - ProgressCall() - SendCallSuppInfo() - Join() - Unjoin() - TerminateCall() - CallTransferRequest() - CallTransferProgress() - CallTransferResponse()
Playing/recording audio
- PlayStream() - RecordStream() - PauseStream() - ResumeStream() - StopStream()
Digits (tone) and events:
- PlayDigit() - StartDigitCollection() - StopDigitCollection() - PlayEvent() - CancelEvent() - StartEventCollection() - StopEventCollection()
Controlling profile or stats:
- SetProfile() - ChangeProfile() - GetStats()
States can be queried instantly:
IsTerminating() IsAccepted() IsAlerted() IsAnswered() IsSynchronized() IsJoined()
Call information can be queried instantly:
GetLegId() GetLinkId() GetAttributes() GetProfile() GetJoinAttributes()
Events received from call legs by the CTBCAFCallFlow object
Initialization and termination of call leg objects:
- OnInitIncomingCallLeg() - OnInitOutgoingCallLeg() - OnLegFreed()
Controlling call flow:
- OnCallLegAccepted() - OnCallLegAlerting() - OnCallLegAnswered() - OnCallLegSuppInfo() - OnLegJoinDone() - OnLegUnjoinDone() - OnCallLegTerminatingIndication() - OnCallLegTerminated() - OnLegTerminated() - OnCallLegTransferRequest() - OnCallLegTransferProgress() - OnCallLegTransferResponse()
Re-synchronization with toolpack_engine:
- OnSyncDone() - OnSyncLost()
Timers or custom events:
- OnLegEvent()
Errors detected by toolpack_engine:
- OnLegError()
Playing/recording audio
- OnStreamPlayingDone() - OnStreamRecordingDone()
Digits (tone) and events:
- OnDigitPlayingDone() - OnDigitCollected() - OnEventPlayingDone() - OnEventCollected()
Controlling profile or stats:
- OnLegProfileChanged() - OnLegStatsUpdated()
Events behavior chain
All the events describe above are called consecutively on each behavior attached to the call flow, and ultimately, called on the call flow itself.
Each behavior in the chain can
- Pass the event to the next behavior in the chain
- Consume the event so other behaviors in the chain and the call flow are unaware that this event occurred
The CTBCAFCallBehavior default implementation is to forward the event to the next event in the chain.
When you implement your own behaviors, you can override only a couple of events (like OnCallLegAnswered() for example) to perform specific tasks, and leave all other events to the base class, so you don't have to write a lot of code to create a new behavior.
Creating the CTBCAFCallFlow object and it's legs
Steps to create a new call flow are:
- Create a new object (using a class derived from CTBCAFCallFlow class)
- Attach behaviors to the call flow
- Add attributes of incoming and outgoing legs to create
- Tell the call flow object to initialize itself, and create the call legs as requested
Here is an example:
ITBCAFCallFlow* pCallFlow; ITBCAFCallFlow* pParentCallOrBehavior; // Create the call flow object (here using the CTBCAFBridge class, based on CTBCAFCallFlow) pCallFlow = tbnew CTBCAFBridge( 0, this); // Optionally, attach behaviors pParentCallOrBehavior = pCallFlow; pParentCallOrBehavior = tbnew CTBCAFCallBehaviorBusyTone( pParentCallOrBehavior, ... ); pParentCallOrBehavior = tbnew CTBCAFCallBehaviorBridgeCdr( pParentCallOrBehavior, ... ); // Add an incoming call leg to that call flow (CTBCAFCallLeg object will get created based on provided attributes) pCallFlow->AddIncoming( in_LegId, ptrIncomingLegAttribute, ptrIncomingLegProtocolAttributes, ptrAcceptCallProtAttribute ); // Add an outgoing call leg pCallFlow->AddOutgoing( ptrOutgoingLegAttribute, ptrOutgoingLegProtocolAttributes ); // Initialize the call (this actually creates the call legs) pCallFlow->InitCall( &pCallFlow );
For a more complete code example, please refer to the simple_call application, in file CTBS2GWSimpleCall.cpp file, or here:
Constructing leg attributes
Incoming call leg attributes
To create the incoming call leg, the following information is required:
- Smart pointer to incoming call leg attributes, received from toolpack_engine through OnCallLegPresent().
ptrIncomingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE( *(in_CallLegAttribute.GetCallLegAttribute()) );
- Smart pointer to incoming call leg attributes, received from toolpack_engine through OnCallLegPresent().
ptrIncomingLegProtocolAttributes = tbnew CTBCMC_PROTOCOL_ATTRIBUTE( in_ProtocolAttribute, TBX_TRUE );
- Smart pointer to empty protocol attributes that Behaviors can fill, and that will be used when accepting the call
Outgoing call leg attributes
To create the outgoing call leg, the following information is required:
- Smart pointer to outgoing call leg attributes to use to create the call, generally derived from the incoming call attributes
ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE(); ptrOutgoingLegAttribute->CopyLegAttributeFrom( *(ptrIncomingLegAttribute.Get()) );
- Smart pointer to empty protocol attributes that Behaviors can fill, and that will be used when creating the outgoing call (SIP invite, ISUP IAM, ISDN Setup, etc.)
Call leg initialization callbacks
All behaviors attached to the call flow will be notified of the creation of new call legs through callback OnInitIncomingCallLeg or OnInitOutgoingCallLeg.
OnInitIncomingCallLeg()
In this callback, each behavior may consult the incoming call attributes or protocol attributes, and can modify the protocol attributes that will be used to accept the call (actually providing protocol-specific information, like SS7 IEs, or SIP headers).
OnInitOutgoingCallLeg()
In this callback, each behavior can modify the protocol attributes that will be used to create the call (actually providing protocol-specific information, like SS7 IEs, or SIP headers that will be used in the initial signaling message, as SIP Invite, ISUP IAM, or ISDN Setup).
Destruction the CTBCAFCallFlow object and it's legs
Self-destructing call legs, behaviors, and call flow
The CTBCAFCallFlow object contains smart pointers to it's call legs. Destruction of these call legs will thus occur when removing the last smart pointer reference to the pointed call leg object.
The CAF framework is responsible to determine when a call leg needs to be destroyed, and will call the function OnLegFreed() of all behaviors and of the CTBCAFCallFlow object itself. When CTBCAFCallFlow::OnLegFreed is called, the smart pointer to that leg is removed (eventually causing leg destruction).
Also upon destruction of the last call leg, object based on CTBCAFCallFlow or CTBCAFCallBehavior will delete themselves automatically, by calling the attached "free listener" (that was provided in the constructor of the call flow object).
Call termination callbacks and actions
OnCallLegTerminatingIndication()
This callback means that toolpack_engine has received a termination request from a call leg (SIP Bye, ISUP REL, for example). A typical use of that event is to call TerminateCall() on both incoming and outgoing legs of a call flow, to hangup both sides.
TerminateCall()
It is MANDATORY that this function is called for each call leg before the leg can be destroyed. It's used to confirm to toolpack_engine that the CAF application has terminated with the call leg, and that the signaling can properly be terminated.
It's up to the application, however, to call the function immediately (within OnCallLegTerminatingIndication() for example) or later after doing some more job (like asynchronous database updates, for example)
OnCallLegTerminated()
This callback confirms that toolpack_engine has finished closing the data path and signaling for this call leg. It's the last event that should be received on a call leg (outside OnLegFreed(), of course).
FreeLeg()
It is MANDATORY that this function is called for each call leg after OnCallLegTerminated().
It's up to the application, however, to call the function immediately (within OnCallLegTerminated() for example) or later after doing some more job (like asynchronous database updates, for example)
OnLegFreed()
This callback confirms that the leg is being freed.
It's the last chance for a call flow or a behavior to release things related to a call leg, like canceling timers for example.
The base classes CTBCAFCallBehavior and CTBCAFCallFlow
- Important note: Behaviors that implement that function MUST, as the LAST line of their function, call the base class' CTBCAFCallBehavior::OnLegFreed. Not calling base class' function will cause the call to leak. Calling that before the last line of the function will cause crash, as the Behavior object will destroy itself within that function upon destruction of the last leg of the call.