CAF: Leg Creation Samples

From TBwiki
(Difference between revisions)
Jump to: navigation, search
(Bridging an Incoming Call (using CTBCAFBridge ))
m (really old article. Removed the needs revising category tag.)
 
(58 intermediate revisions by 4 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 7: Line 7:
 
     ptrOutgoingLegAttribute->GetNetworkAccessPoint()  = "NAP_SS7_MONTREAL";
 
     ptrOutgoingLegAttribute->GetNetworkAccessPoint()  = "NAP_SS7_MONTREAL";
 
    
 
    
     PTRCTBCAFCallLeg ptrOutgoingCallLeg = CreateOutgoingCallLeg(ptrOutgoingLegAttribute);
+
     PCTBCMCLeg pCallLeg = tbnew CTBCMCLeg( ++mun32LegId, ptrOutgoingLegAttribute, this, 0, &mLegMutex );
 +
    pCallLeg->CreateCall();
  
==== Bridging an Incoming Call (manual method)====
+
== Bridging an Incoming Call Leg (using CTBCAFBridge )==
  TODO ADD SAMPLE CODE
+
==== Bridging an Incoming Call (using CTBCAFBridge )====
+
  
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrIncomingCallLegAttribute;
+
TBX_VOID CTBS2GWSimpleCall::OnCallLegPresent
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingCallLegAttribute;
+
(
  PITBCAFCallFlow       pCallFlow;
+
  IN TBCMC_LEG_ID in_LegId,
 
+
  IN CTBCMC_CALL_LEG_ATTRIBUTE_COMMON & in_CallLegAttribute,
  ptrOutgoingCallLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();
+
  IN CTBCMC_PROTOCOL_ATTRIBUTE & in_ProtocolAttribute
  ptrIncomingCallLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE(*pCallLegAttribute);
+
)
 
+
{
  ptrOutgoingLegAttribute->GetCalledNumber()         = ptrIncomingCallLegAttribute->GetCallingNumber();
+
TBX_RESULT Result;
  ptrOutgoingLegAttribute->GetCallingNumber()       = ptrIncomingCallLegAttribute->GetCalledNumber();
+
PITBCAFCallFlow pBridge;
  ptrOutgoingLegAttribute->GetNetworkAccessPoint()  = ptrIncomingCallLegAttribute->GetNetworkAccessPoint();
+
PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrIncomingLegAttribute;
 
+
PTRCTBCMC_PROTOCOL_ATTRIBUTE ptrIncomingLegProtocolAttributes;
  pCallFlow = tbnew CTBCAFSignalingBridge( mun32AccountId, this );
+
PTRCTBCMC_PROTOCOL_ATTRIBUTE ptrAcceptCallProtAttribute;
  TBCAF_EXIT_ON_NULL( pCallFlow, TBX_RESULT_FAIL, "Failed to allocate call." );
+
PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;
 
+
PTRCTBCMC_PROTOCOL_ATTRIBUTE ptrOutgoingLegProtocolAttributes;
  Result = pCallFlow->AddIncoming( mun32LegId, ptrIncomingCallLegAttribute );
+
  TBCAF_EXIT_ON_ERROR(Result, "AddIncoming Failed." );
+
 
+
/*---------------------------------------------------------------------------------------------------------------------------
  Result = pCallFlow->AddOutgoing( ptrOutgoingCallLegAttribute );
+
|  Code section
  TBCAF_EXIT_ON_ERROR(Result, "AddOutgoing Failed." );
+
*--------------------------------------------------------------------------------------------------------------------------*/
   
+
CAFCODE( CTBS2GWSimpleCall::OnCallLegPresent )
  // Start the call
+
{
  Result = pCallFlow->InitCall( &pCallFlow );
+
// 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 ==
  
==== Creating a Media-only Leg ====
+
===If you are using a nap of type NAP_MEDIA_TDM:===
If you are using the NAP_MEDIA_TDM:
+
 
      
 
      
 
     PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;
 
     PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;
Line 43: 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_SS7_MONTREAL";
+
     ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_TDM";
 
     pMediaDesc->Type                              = TBCMC_MEDIA_TYPE_AUDIO;
 
     pMediaDesc->Type                              = TBCMC_MEDIA_TYPE_AUDIO;
 
     pMediaDesc->Transport                        = TBCMC_MEDIA_TRANSPORT_TDM;
 
     pMediaDesc->Transport                        = TBCMC_MEDIA_TRANSPORT_TDM;
Line 60: Line 148:
 
     pCallLeg->CreateCall();
 
     pCallLeg->CreateCall();
  
If you are using the NAP_MEDIA_VOIP:
+
===If you are using a nap of type NAP_MEDIA_VOIP:===
  
 
     TBX_RESULT                        Result;
 
     TBX_RESULT                        Result;
Line 68: 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_SS7_MONTREAL";
+
     ptrLegAttribute->GetNetworkAccessPoint()      = "NAP_MEDIA_VOIP";
 
     pMediaDesc->Type                              = TBCMC_MEDIA_TYPE_AUDIO;
 
     pMediaDesc->Type                              = TBCMC_MEDIA_TYPE_AUDIO;
 
     pMediaDesc->Transport                        = TBCMC_MEDIA_TRANSPORT_IP;
 
     pMediaDesc->Transport                        = TBCMC_MEDIA_TRANSPORT_IP;
Line 78: 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 );
 
     pCallLeg->CreateCall();
 
     pCallLeg->CreateCall();
  
To see how to fill a TBX_SDP_INFO structure (implementation of BuildSdpInfo()), refer to [[Customer_Application_Framework_:_Filling_SDP_Structure|Filling an SDP Structure]].
+
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 [[Customer_Application_Framework_:_Filling_SDP_Structure|Filling an SDP Structure]].
 +
 
 +
 
 +
 
 +
[[category:CAF]]

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