CAF: Leg Creation Samples

From TBwiki
(Difference between revisions)
Jump to: navigation, search
(If you are using a nap of type NAP_MEDIA_VOIP:)
m (really old article. Removed the needs revising category tag.)
 
(10 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== Creating a Standalone Outgoing Call ==
+
== Creating a Standalone Outgoing Call Leg ==
 
     PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;
 
     PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;
 
     ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
 
     ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
Line 10: Line 10:
 
     pCallLeg->CreateCall();
 
     pCallLeg->CreateCall();
  
== Bridging an Incoming Call (manual method)==
+
== Bridging an Incoming Call Leg (using CTBCAFBridge )==
  TBX_VOID CTBCAFMediaGateway::OnCallLegPresent
+
 
  (
+
TBX_VOID CTBS2GWSimpleCall::OnCallLegPresent
    IN TBCMC_LEG_ID in_LegId,
+
(
    IN CTBCMC_CALL_LEG_ATTRIBUTE_COMMON & in_CallLegAttribute,
+
  IN TBCMC_LEG_ID in_LegId,  
    IN CTBCMC_PROTOCOL_ATTRIBUTE & in_ProtocolAttribute
+
  IN CTBCMC_CALL_LEG_ATTRIBUTE_COMMON & in_CallLegAttribute,  
  )
+
  IN CTBCMC_PROTOCOL_ATTRIBUTE & in_ProtocolAttribute
  {
+
)
  TBCAF_MUTEX_GET_SCOPE_BEGIN( &mMutex )
+
{
        PCTBCMC_CALL_LEG_ATTRIBUTE pCallLegAttribute;
+
TBX_RESULT Result;
        PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrIncomingCallLegAttribute;
+
PITBCAFCallFlow pBridge;
        PTRCTBCMC_CALL_LEG_ATTRIBUTE   ptrOutgoingCallLegAttribute;
+
PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrIncomingLegAttribute;
  /*---------------------------------------------------------------------------------------------------------------------------
+
PTRCTBCMC_PROTOCOL_ATTRIBUTE ptrIncomingLegProtocolAttributes;
  |  Code section
+
PTRCTBCMC_PROTOCOL_ATTRIBUTE ptrAcceptCallProtAttribute;
  *--------------------------------------------------------------------------------------------------------------------------*/
+
PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;
  CAFCODE( CTBCAFMediaGateway::OnCallLegPresent )
+
PTRCTBCMC_PROTOCOL_ATTRIBUTE ptrOutgoingLegProtocolAttributes;
  {
+
                pCallLegAttribute          = in_CallLegAttribute.GetCallLegAttribute();
+
                ptrIncomingCallLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE(*pCallLegAttribute);
+
/*---------------------------------------------------------------------------------------------------------------------------
                ptrOutgoingCallLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
+
|  Code section
 
+
*--------------------------------------------------------------------------------------------------------------------------*/
                ptrOutgoingCallLegAttribute->GetCalledNumber()         = ptrIncomingCallLegAttribute->GetCallingNumber();
+
CAFCODE( CTBS2GWSimpleCall::OnCallLegPresent )
                ptrOutgoingCallLegAttribute->GetCallingNumber()       = ptrIncomingCallLegAttribute->GetCalledNumber();
+
{
                ptrOutgoingCallLegAttribute->GetNetworkAccessPoint()   = ptrIncomingCallLegAttribute->GetNetworkAccessPoint();
+
// Create smart pointers to incoming call leg attributes so behaviors can keep reference to it if needed
   
+
ptrIncomingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE( *(in_CallLegAttribute.GetCallLegAttribute()) );
                PCTBCMCLeg pIncomingCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrIncomingCallLegAttribute, this, 0, &mLegMutex );
+
ptrIncomingLegProtocolAttributes = tbnew CTBCMC_PROTOCOL_ATTRIBUTE( in_ProtocolAttribute, TBX_TRUE );
                pIncomingCallLeg->CreateCall();
+
   
+
// Build default protocol attributes object so behaviors can modify
                PCTBCMCLeg pOutgoingCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrOutgoingCallLegAttribute, this, 0, &mLegMutex );
+
// attributes used to Accept the incoming call leg
                pOutgoingCallLeg->CreateCall();
+
ptrAcceptCallProtAttribute = tbnew CTBCMC_PROTOCOL_ATTRIBUTE();
   
+
        TBX_EXIT_SUCCESS( TBX_RESULT_OK );
+
// Build default protocol attributes object so behaviors can modify
  }
+
// attributes used to create the outgoing call leg
 
+
ptrOutgoingLegProtocolAttributes = tbnew CTBCMC_PROTOCOL_ATTRIBUTE();
  /*---------------------------------------------------------------------------------------------------------------------------
+
  |  Exception handling section
+
// Create an empty outgoing call leg attribute object
  *--------------------------------------------------------------------------------------------------------------------------*/
+
ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
  CAF_EXCEPTION_HANDLING
+
 
+
// Fill some information in the outgoing call leg attributes from the incoming leg attributes
  /*---------------------------------------------------------------------------------------------------------------------------
+
// *** Warning: Don't use operator=. We dont wan't to copy EVERYTHING, but only information
  |  Error handling section
+
// common to both incoming and outgoing legs, such as calling/called number.
  *--------------------------------------------------------------------------------------------------------------------------*/
+
// Function CopyLegAttributeFrom() takes care of copying relevant information.
  CAF_ERROR_HANDLING( CAF_VERBOSE )
+
ptrOutgoingLegAttribute->CopyLegAttributeFrom( *(ptrIncomingLegAttribute.Get()) );
  {
+
  }
+
// Create the call (i.e. which contains 2 call legs)
 
+
pBridge = tbnew CTBCAFBridge( 0, this );
  /*---------------------------------------------------------------------------------------------------------------------------
+
TBCAF_EXIT_ON_NULL( pBridge, TBX_RESULT_FAIL, "Failed to allocate call." );
  |  Cleanup section
+
  *--------------------------------------------------------------------------------------------------------------------------*/
+
/* Prepare the chain of behaviors */
  CAF_CLEANUP
+
PITBCAFCallFlow pPreviousBehavior = pBridge;
  {
+
  }
+
/* Add the example behavior to the chain of behaviors */
 
+
pPreviousBehavior = tbnew CTBS2GWCallBehaviorExample( pPreviousBehavior );
  RETURN_VOID;
+
  TBCAF_MUTEX_GET_SCOPE_END( &mMutex )
+
// Add legs information
  }
+
Result = pBridge->AddIncoming( in_LegId, ptrIncomingLegAttribute, ptrIncomingLegProtocolAttributes, ptrAcceptCallProtAttribute );
Incoming and outgoing call leg will be joined when we receive the notification OnCallLegAnswered() indicating that the outgoing call has been answered by the remote peer.
+
TBCAF_EXIT_ON_ERROR(Result, "AddIncoming Failed." );
 +
 +
// Provide an uninitialized PTRCTBCMC_PROTOCOL_ATTRIBUTE
 +
Result = pBridge->AddOutgoing( ptrOutgoingLegAttribute, ptrOutgoingLegProtocolAttributes );
 +
TBCAF_EXIT_ON_ERROR(Result, "AddOutgoing Failed." );
 +
 +
 +
Result = pBridge->InitCall( &pBridge );
 +
if( pBridge == NULL )
 +
{
 +
/* Note: If this return value is NULL, this means the InitCall function
 +
has initialized no call leg's state machine (failed to) and
 +
destroyed itself immediately (it normally destroys itself later
 +
when the state machine of all call legs has terminated).
 +
The above line of code shall thus be the last of the function
 +
to avoid accessing any member of "this" here. */
 +
TBX_EXIT_CLEANUP( Result );
 +
}
 +
TBCAF_EXIT_ON_ERROR(Result, "InitCall Failed." );
 +
 +
TBX_EXIT_SUCCESS( TBX_RESULT_OK );
 +
}
 +
 +
/*---------------------------------------------------------------------------------------------------------------------------
 +
|  Exception handling section
 +
*--------------------------------------------------------------------------------------------------------------------------*/
 +
CAF_EXCEPTION_HANDLING
 +
 +
/*---------------------------------------------------------------------------------------------------------------------------
 +
|  Error handling section
 +
*--------------------------------------------------------------------------------------------------------------------------*/
 +
CAF_ERROR_HANDLING( CAF_VERBOSE )
 +
{
 +
if( pBridge == NULL )
 +
{
 +
// Try to refuse the call leg
 +
CTBCMCLeg::RefuseLeg( in_LegId, in_CallLegAttribute );
 +
}
 +
}
 +
 +
/*---------------------------------------------------------------------------------------------------------------------------
 +
|  Cleanup section
 +
*--------------------------------------------------------------------------------------------------------------------------*/
 +
CAF_CLEANUP
 +
{
 +
}
 +
 +
RETURN_VOID;
 +
}
  
== Bridging an Incoming Call (using CTBCAFBridge )==
 
  
  TBX_VOID CTBCAFMediaGateway::OnCallLegPresent
 
  (
 
    IN TBCMC_LEG_ID in_LegId,
 
    IN CTBCMC_CALL_LEG_ATTRIBUTE_COMMON & in_CallLegAttribute,
 
    IN CTBCMC_PROTOCOL_ATTRIBUTE & in_ProtocolAttribute
 
  )
 
  {
 
  TBCAF_MUTEX_GET_SCOPE_BEGIN( &mMutex )
 
        PCTBCMC_CALL_LEG_ATTRIBUTE pCallLegAttribute;
 
        PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrIncomingCallLegAttribute;
 
        PTRCTBCMC_CALL_LEG_ATTRIBUTE    ptrOutgoingCallLegAttribute;
 
        PITBCAFCallFlow                pCallFlow;
 
        TBX_RESULT                      Result;
 
  /*---------------------------------------------------------------------------------------------------------------------------
 
  |  Code section
 
  *--------------------------------------------------------------------------------------------------------------------------*/
 
  CAFCODE( CTBCAFMediaGateway::OnCallLegPresent )
 
  {
 
                pCallLegAttribute          = in_CallLegAttribute.GetCallLegAttribute();
 
                ptrIncomingCallLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE(*pCallLegAttribute);
 
                ptrOutgoingCallLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
 
 
 
                ptrOutgoingCallLegAttribute->GetCalledNumber()        = ptrIncomingCallLegAttribute->GetCallingNumber();
 
                ptrOutgoingCallLegAttribute->GetCallingNumber()        = ptrIncomingCallLegAttribute->GetCalledNumber();
 
                ptrOutgoingCallLegAttribute->GetNetworkAccessPoint()  = ptrIncomingCallLegAttribute->GetNetworkAccessPoint();
 
 
 
                pCallFlow = tbnew CTBCAFBridge( mun32AccountId, this );
 
                TBCAF_EXIT_ON_NULL( pCallFlow, TBX_RESULT_FAIL, "Failed to allocate call." );
 
 
 
                Result = pCallFlow->AddIncoming( mun32LegId, ptrIncomingCallLegAttribute );
 
                TBCAF_EXIT_ON_ERROR(Result, "AddIncoming Failed." );
 
 
 
                Result = pCallFlow->AddOutgoing( ptrOutgoingCallLegAttribute );
 
                TBCAF_EXIT_ON_ERROR(Result, "AddOutgoing Failed." );
 
   
 
                // Start the call
 
                Result = pCallFlow->InitCall( &pCallFlow );
 
   
 
        TBX_EXIT_SUCCESS( TBX_RESULT_OK );
 
  }
 
 
 
  /*---------------------------------------------------------------------------------------------------------------------------
 
  |  Exception handling section
 
  *--------------------------------------------------------------------------------------------------------------------------*/
 
  CAF_EXCEPTION_HANDLING
 
 
 
  /*---------------------------------------------------------------------------------------------------------------------------
 
  |  Error handling section
 
  *--------------------------------------------------------------------------------------------------------------------------*/
 
  CAF_ERROR_HANDLING( CAF_VERBOSE )
 
  {
 
  }
 
 
 
  /*---------------------------------------------------------------------------------------------------------------------------
 
  |  Cleanup section
 
  *--------------------------------------------------------------------------------------------------------------------------*/
 
  CAF_CLEANUP
 
  {
 
  }
 
 
 
  RETURN_VOID;
 
  TBCAF_MUTEX_GET_SCOPE_END( &mMutex )
 
  }
 
 
InitCall() will create each leg added from AddIncoming() and AddOutgoing() and incoming and outgoing call leg will be joined when we receive the notification OnCallLegAnswered() indicating that the outgoing call has been answered by the remote peer.
 
InitCall() will create each leg added from AddIncoming() and AddOutgoing() and incoming and outgoing call leg will be joined when we receive the notification OnCallLegAnswered() indicating that the outgoing call has been answered by the remote peer.
 +
 +
 +
== Pitfall ==
 +
It's mandatory that the call leg and protocol attribute objects passed to AddIncoming() and AddOutgoing() remain valid until function InitCall() returns.
  
 
== Creating a Media-only Leg ==
 
== Creating a Media-only Leg ==
Line 143: Line 131:
 
    
 
    
 
     ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();
 
     ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();
     pMediaDesc     = &ptrLegAttribute->GetProfile()->MediaDescription;  
+
     pMediaDesc   = &ptrLegAttribute->GetProfile().GetMediaDescription();  
 
   
 
   
 
     ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_TDM";
 
     ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_TDM";
Line 168: Line 156:
 
    
 
    
 
     ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();
 
     ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();
     pMediaDesc   = &ptrLegAttribute->GetProfile()->MediaDescription;
+
     pMediaDesc   = &ptrLegAttribute->GetProfile().GetMediaDescription();
 
    
 
    
 
     ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_VOIP";
 
     ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_VOIP";
Line 178: Line 166:
 
     Result = BuildSdpInfo("", 0, SdpInfo);                // No IP specified, Toolpack will choose one
 
     Result = BuildSdpInfo("", 0, SdpInfo);                // No IP specified, Toolpack will choose one
 
     TBCAF_EXIT_ON_ERROR( Result, "BuildSdpInfo failed." );
 
     TBCAF_EXIT_ON_ERROR( Result, "BuildSdpInfo failed." );
     ptrLegAttribute->SetLocalSDP(&SdpInfo);
+
     ptrLegAttribute->GetProfile().SetLocalSDP(SdpInfo);
 
      
 
      
 
     // Set Peer SDP
 
     // Set Peer SDP
 
     Result = BuildSdpInfo("10.0.0.15", 5000, SdpInfo);    // Using peer IP address and port
 
     Result = BuildSdpInfo("10.0.0.15", 5000, SdpInfo);    // Using peer IP address and port
 
     TBCAF_EXIT_ON_ERROR( Result, "BuildSdpInfo failed." );
 
     TBCAF_EXIT_ON_ERROR( Result, "BuildSdpInfo failed." );
     ptrLegAttribute->SetPeerSDP(&SdpInfo);
+
     ptrLegAttribute->GetProfile().SetPeerSDP(SdpInfo);
 
    
 
    
 
     PCTBCMCLeg pCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrLegAttribute, this, 0, &mLegMutex );
 
     PCTBCMCLeg pCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrLegAttribute, this, 0, &mLegMutex );
Line 190: Line 178:
 
Note that you have two possibilities to build a TBX_SDP_INFO structure. The first one is like in the example (BuildSdpInfo()) where you can build manually your TBX_SDP_INFO structure and the second one is when you have an sdp info in text format. There is a function that will parse the text and build a TBX_SDP_INFO structure from it.
 
Note that you have two possibilities to build a TBX_SDP_INFO structure. The first one is like in the example (BuildSdpInfo()) where you can build manually your TBX_SDP_INFO structure and the second one is when you have an sdp info in text format. There is a function that will parse the text and build a TBX_SDP_INFO structure from it.
  
   TBX_RESULT TBXMediaLibSdpParse2
+
   TBXMediaLibSdpParse
 
   (
 
   (
    IN    PTBX_CHAR                        in_pszSdp,
+
      IN    PTBX_CHAR                        in_pszSdp,
    OUT  PTBX_SDP_INFO                    out_pSdpInfo,
+
      OUT  PTBX_SDP_INFO                    out_pSdpInfo,
    IN    TBX_MEDIA_SDP_PARSE_OPTIONS      in_Options,
+
      IN    TBX_MEDIA_SDP_PARSE_OPTIONS      in_Options
    OUT  PTBX_CHAR                        out_pszErrMsg,
+
    IN    TBX_UINT32                      in_un32MaxErrMsgLen
+
 
   );
 
   );
  
To see how to build a TBX_SDP_INFO structure (implementation of BuildSdpInfo()), refer to [[Customer_Application_Framework_:_Filling_SDP_Structure|Filling an SDP Structure]].
+
To see how to build a TBX_SDP_INFO structure, refer to [[Customer_Application_Framework_:_Filling_SDP_Structure|Filling an SDP Structure]].
  
  
  
 
[[category:CAF]]
 
[[category:CAF]]
[[category:Needs revising]]
 

Latest revision as of 14:53, 22 February 2018

Contents

Creating a Standalone Outgoing Call Leg

   PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;
   ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
 
   ptrOutgoingLegAttribute->GetCalledNumber()         = "123-4567";
   ptrOutgoingLegAttribute->GetCallingNumber()        = "987-6543";
   ptrOutgoingLegAttribute->GetNetworkAccessPoint()   = "NAP_SS7_MONTREAL";
 
   PCTBCMCLeg pCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrOutgoingLegAttribute, this, 0, &mLegMutex );
   pCallLeg->CreateCall();

Bridging an Incoming Call Leg (using CTBCAFBridge )

TBX_VOID CTBS2GWSimpleCall::OnCallLegPresent
(
  IN	TBCMC_LEG_ID						in_LegId, 
  IN	CTBCMC_CALL_LEG_ATTRIBUTE_COMMON &	in_CallLegAttribute, 
  IN	CTBCMC_PROTOCOL_ATTRIBUTE &			in_ProtocolAttribute
)
{
	TBX_RESULT								Result;
	PITBCAFCallFlow			 				pBridge;
	PTRCTBCMC_CALL_LEG_ATTRIBUTE			ptrIncomingLegAttribute;
	PTRCTBCMC_PROTOCOL_ATTRIBUTE			ptrIncomingLegProtocolAttributes;
	PTRCTBCMC_PROTOCOL_ATTRIBUTE			ptrAcceptCallProtAttribute;
	PTRCTBCMC_CALL_LEG_ATTRIBUTE			ptrOutgoingLegAttribute;
	PTRCTBCMC_PROTOCOL_ATTRIBUTE			ptrOutgoingLegProtocolAttributes;


	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Code section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CAFCODE( CTBS2GWSimpleCall::OnCallLegPresent )
	{
		// Create smart pointers to incoming call leg attributes so behaviors can keep reference to it if needed
		ptrIncomingLegAttribute				= tbnew CTBCMC_CALL_LEG_ATTRIBUTE( *(in_CallLegAttribute.GetCallLegAttribute()) );
		ptrIncomingLegProtocolAttributes	= tbnew CTBCMC_PROTOCOL_ATTRIBUTE( in_ProtocolAttribute, TBX_TRUE );

		// Build default protocol attributes object so behaviors can modify
		// attributes used to Accept the incoming call leg
		ptrAcceptCallProtAttribute			= tbnew CTBCMC_PROTOCOL_ATTRIBUTE();

		// Build default protocol attributes object so behaviors can modify 
		// attributes used to create the outgoing call leg
		ptrOutgoingLegProtocolAttributes	= tbnew CTBCMC_PROTOCOL_ATTRIBUTE();

		// Create an empty outgoing call leg attribute object
		ptrOutgoingLegAttribute		= tbnew CTBCMC_CALL_LEG_ATTRIBUTE();

		// Fill some information in the outgoing call leg attributes from the incoming leg attributes
		// *** Warning: Don't use operator=. We dont wan't to copy EVERYTHING, but only information
		//				common to both incoming and outgoing legs, such as calling/called number.
		//				Function CopyLegAttributeFrom() takes care of copying relevant information.
		ptrOutgoingLegAttribute->CopyLegAttributeFrom( *(ptrIncomingLegAttribute.Get()) );

		// Create the call (i.e. which contains 2 call legs)
		pBridge = tbnew CTBCAFBridge( 0, this );
		TBCAF_EXIT_ON_NULL( pBridge, TBX_RESULT_FAIL, "Failed to allocate call." );

		/* Prepare the chain of behaviors */
		PITBCAFCallFlow pPreviousBehavior = pBridge;

		/* Add the example behavior to the chain of behaviors */
		pPreviousBehavior = tbnew CTBS2GWCallBehaviorExample( pPreviousBehavior );

		// Add legs information
		Result = pBridge->AddIncoming( in_LegId, ptrIncomingLegAttribute, ptrIncomingLegProtocolAttributes, ptrAcceptCallProtAttribute );
		TBCAF_EXIT_ON_ERROR(Result, "AddIncoming Failed." );
		
		// Provide an uninitialized PTRCTBCMC_PROTOCOL_ATTRIBUTE
		Result = pBridge->AddOutgoing( ptrOutgoingLegAttribute, ptrOutgoingLegProtocolAttributes );
		TBCAF_EXIT_ON_ERROR(Result, "AddOutgoing Failed." );


		Result = pBridge->InitCall( &pBridge );
		if( pBridge == NULL )
		{
			/* Note: If this return value is NULL, this means the InitCall function
					 has initialized no call leg's state machine (failed to) and
					 destroyed itself immediately (it normally destroys itself later
					 when the state machine of all call legs has terminated).
					 The above line of code shall thus be the last of the function
					 to avoid accessing any member of "this" here. */
			TBX_EXIT_CLEANUP( Result );
		}
		TBCAF_EXIT_ON_ERROR(Result, "InitCall Failed." );

		TBX_EXIT_SUCCESS( TBX_RESULT_OK );
	}

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Exception handling section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CAF_EXCEPTION_HANDLING

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Error handling section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CAF_ERROR_HANDLING( CAF_VERBOSE )
	{
		if( pBridge == NULL )
		{
			// Try to refuse the call leg
			CTBCMCLeg::RefuseLeg( in_LegId, in_CallLegAttribute );
		}
	}

	/*---------------------------------------------------------------------------------------------------------------------------
	 |  Cleanup section
	 *--------------------------------------------------------------------------------------------------------------------------*/
	CAF_CLEANUP
	{
	}

	RETURN_VOID;
}


InitCall() will create each leg added from AddIncoming() and AddOutgoing() and incoming and outgoing call leg will be joined when we receive the notification OnCallLegAnswered() indicating that the outgoing call has been answered by the remote peer.


Pitfall

It's mandatory that the call leg and protocol attribute objects passed to AddIncoming() and AddOutgoing() remain valid until function InitCall() returns.

Creating a Media-only Leg

If you are using a nap of type NAP_MEDIA_TDM:

   PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;
   PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;
 
   ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();
   pMediaDesc	  = &ptrLegAttribute->GetProfile().GetMediaDescription(); 

   ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_TDM";
   pMediaDesc->Type                              = TBCMC_MEDIA_TYPE_AUDIO;
   pMediaDesc->Transport                         = TBCMC_MEDIA_TRANSPORT_TDM;
   pMediaDesc->Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;
   pMediaDesc->Settings.TdmAudio.un8Timeslot     = 5;
   Strncpy
   (
       pMediaDesc->Settings.TdmAudio.szTrunkName, 
       "TRUNK_TORONTO_1", 
       sizeof(pMediaDesc->Settings.TdmAudio.szTrunkName)
   );
 
   PCTBCMCLeg pCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrLegAttribute, this, 0, &mLegMutex );
   pCallLeg->CreateCall();

If you are using a nap of type NAP_MEDIA_VOIP:

   TBX_RESULT                         Result;
   TBX_SDP_INFO                       SdpInfo;
   PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;
   PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;
 
   ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();
   pMediaDesc	   = &ptrLegAttribute->GetProfile().GetMediaDescription();
 
   ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_VOIP";
   pMediaDesc->Type                              = TBCMC_MEDIA_TYPE_AUDIO;
   pMediaDesc->Transport                         = TBCMC_MEDIA_TRANSPORT_IP;
   pMediaDesc->Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;
  
   // Set Local SDP
   Result = BuildSdpInfo("", 0, SdpInfo);                 // No IP specified, Toolpack will choose one
   TBCAF_EXIT_ON_ERROR( Result, "BuildSdpInfo failed." );
   ptrLegAttribute->GetProfile().SetLocalSDP(SdpInfo);
   
   // Set Peer SDP
   Result = BuildSdpInfo("10.0.0.15", 5000, SdpInfo);     // Using peer IP address and port
   TBCAF_EXIT_ON_ERROR( Result, "BuildSdpInfo failed." );
   ptrLegAttribute->GetProfile().SetPeerSDP(SdpInfo);
 
   PCTBCMCLeg pCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrLegAttribute, this, 0, &mLegMutex );
   pCallLeg->CreateCall();

Note that you have two possibilities to build a TBX_SDP_INFO structure. The first one is like in the example (BuildSdpInfo()) where you can build manually your TBX_SDP_INFO structure and the second one is when you have an sdp info in text format. There is a function that will parse the text and build a TBX_SDP_INFO structure from it.

 TBXMediaLibSdpParse
 (
     IN    PTBX_CHAR                        in_pszSdp,
     OUT   PTBX_SDP_INFO                    out_pSdpInfo,
     IN    TBX_MEDIA_SDP_PARSE_OPTIONS      in_Options
 );

To see how to build a TBX_SDP_INFO structure, refer to Filling an SDP Structure.

Personal tools