Actions

CMC Call Leg class

Revision as of 10:20, 7 September 2022 by Allyntree (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


CTBCMCCallLeg Hierarchy.jpg

An instance of the class CTBCMCCallLeg represents a combination of one full-duplex media resource and its associated signaling entity. Typical examples would be an SS7 ISUP call with its associated CIC (mapped to a TDM interface such as a T1 timeslot) or a SIP call with its associated Voip codec resource (attached to an IP/UDP endpoint).

This class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones). Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/Voip, ISDN, SS7, etc).


Usage

Although a typical application connects call legs together to achieve a bridge, the following example show an application where outgoing call leg is created to handle the signaling, play a prompt and disconnect.

Pager application : In this example, we want to create an outgoing call leg, wait until the called party answers, play a message (prompt) and disconnect the call leg. This can be achieved by creating a custom class for our application inheriting from the CTBCMCCallLeg class. Since we only want to act when the called party answers the phone, we only need to overload the base class member function OnCallAnswered() and insert the piece of code to play the prompt there. As the prompt playing is asynchronous, we want to terminate the call leg only once the complete prompt is played. To do so, overloading the OnStreamPlayDone() base class member function. When it is called, we act on the call leg by calling the base class Terminate() member function. The call will then terminate itself.

 //
 // Class definition
 //
 typedef class CTBS2GWSimpleCallPager *PCTBS2GWSimpleCallPager;
 class CTBS2GWSimpleCallPager : public CTBCMCCallLeg
 {
 public:
   CTBS2GWSimpleCallPager( TBCMC_LEG_ID, CTBCAFPtr<CTBCMC_CALL_LEG_ATTRIBUTE>, PITBCMCLegFreeListener );
   virtual ~CTBS2GWSimpleCallPager( );
 private:
   // Overloaded member functions of the base class
   TBX_VOID OnCallAnswered( PTBCMC_MSG_NOTIF_CALL_LEG_ANSWERED );
   TBX_VOID OnStreamPlayingDone( PTBCMC_MSG_NOTIF_PLAYING_DONE );
   TBX_VOID OnCallTerminatingIndication( PTBCMC_MSG_NOTIF_CALL_LEG_TERMINATING_INDICATION );
   TBX_VOID OnCallTerminated( PTBCMC_MSG_NOTIF_CALL_LEG_TERMINATED );
 };
 //
 // Constructor - Nothing special to do except passing the call leg attributes
 //
 CTBS2GWSimpleCallPager::CTBS2GWSimpleCallPager
 (
   IN TBCMC_LEG_ID in_LegId,
   IN CTBCAFPtr<CTBCMC_CALL_LEG_ATTRIBUTE> in_ptrCallLegAttribute,
   IN PITBCMCLegFreeListener in_pFreeListener
 ) : CTBCMCCallLeg (in_LegId, in_ptrCallLegAttribute, in_pFreeListener, NULL)
 {
 }
 //
 // Destructor - Nothing special to do.
 //
 CTBS2GWSimpleCallPager::~CTBS2GWSimpleCallPager()
 {
 }
 //
 // ::OnCallAnswered
     // Act when outgoing call leg is answered. We play a prompt and wait for its completion
 //
 TBX_VOID CTBS2GWSimpleCallPager::OnCallAnswered
 (
 IN   PTBCMC_MSG_NOTIF_CALL_LEG_ANSWERED in_phMsg
 )
 {
   CTBCMC_PLAY_ATTRIBUTE PlayAttribute;
   // Play a prompt asynchronously (relative to the signaling call handling)
   PlayAttribute.AddPlayFilePath ( "tbdb://file_55.wav" );
   PlayStream (&PlayAttribute);
 }
 //
 // ::OnStreamPlayingDone
 // Act when the prompt play is done. We simply terminate the call leg.
 //
 TBX_VOID CTBS2GWSimpleCallPager::OnStreamPlayingDone
 (
   IN PTBCMC_MSG_NOTIF_PLAYING_DONE in_phMsg
 )
 {
     TBCMC_CALL_REASON Reason;
     // Simply terminate the call leg.
     Reason.Reason = TBCMC_CALL_REASON_CODE_NORMAL;
     TerminateCall( &Reason );
 }
 //
 // ::OnCallTerminatingIndication
 // Act when the call leg is terminating (i.e. closed by the network). Simply confirms by

// starting the termination of the leg. // TBX_VOID CTBS2GWSimpleCallPager::OnCallTerminatingIndication ( IN PTBCMC_MSG_NOTIF_CALL_LEG_TERMINATING_INDICATION in_phMsg ) { // Simply terminate the call leg using the same reason as the indication. TerminateCall( &(in_phMsg->Event.Reason) ); }

// // ::OnCallTerminated // Act when the call leg is terminated. Simply call the free so that the object owner deletes it. // TBX_VOID CTBS2GWSimpleCallPager::OnCallTerminated ( IN PTBCMC_MSG_NOTIF_CALL_LEG_TERMINATED in_phMsg ) { FreeLeg(); } // // This piece of code is executed from the main application to create the outgoing call leg. // { PCTBS2GWSimpleCallPager pCallLeg = NULL; TBCMC_CALL_LEG_ATTRIBUTE LegAttribute = {0}; CTBCAFPtr<CTBCMC_CALL_LEG_ATTRIBUTE> ptrLegAttribute; // Allocate new call attributes ptrLegAttribute = new CTBCMC_CALL_LEG_ATTRIBUTE; // Set the call leg attribute (called/calling number, text name of the outgoing // network to use, etc.) strcpy (LegAttribute.NetworkAccessPoint.szName, "TB"); strcpy (LegAttribute.szCallingNumber, "5550001"); strcpy (LegAttribute.szCalledNumber, "3330002"); ptrLegAttribute->CopyFrom (&LegAttribute); pCallLeg = new CTBS2GWSimpleCallPager (un32LegId++, ptrLegAttribute, g_pMainApp); pCallLeg->CreateCall(); }

Caveats

Do not confuse a call leg with a call . A call leg represents one full-duplex link to a party while a call represents the agglomeration of multiple (two or more) call legs. For example, a bridge is a form of call that uses two call legs.

  • Do not confuse the base class CTBCMCCallLeg with the class CTBCAFCallLeg. The later is a class used by the ITBCAFCall interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object. Therefore, the above example used the CTBCMCCallLeg.
  • If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the CTBCAFBridge class instead. This class already deals with the issues of handling multiple legs simultaneously.
  • The call leg attribute is an object containing the call leg information (called/calling numbers, etc) that needs to be allocated by the caller (in this example the ’main’) and given to the call leg object. It will be freed automatically when the leg is destroyed.
  • The base class does not automatically free itself. This is why the member function OnCallTerminated() was overloaded to actually instruct the base class to start the freeing operation once the signaling call is done. In another type of application, some steps could be required before the actual leg free is desired (such as logging, DB access, etc).
  • The ’delete’ operation on the call leg is eventually done by the object exposing the ’freeListener’ interface. This allows the application to centralize (if required) the ownership of objects to a single entity. This means that an object could also self-delete if it is given its own ’freeListener’ interface pointer. This all depends on the hierarchy of object owership the application designer wants to do.

Classes

  • CTBCMCLeg
  • ITBCMCCallLeg