Media Mode


Figure 4: Media mode


As outlined in Figure 4, in the media mode, AnyFirewall™ Engine is only used to transmit audio and video. Integration with SIP stacks in this mode is limited to creating media sessions (i.e. setup RTP and RTCP sockets for audio or video) and exchanging ICE candidates (i.e., IPs and ports that the AnyFirewall™ Engine is listening on for media packets sent from the remote SIP endpoint). AnyFirewall™ Engine handles firewall and NAT traversal for audio and video RTP and RTCP packets. AnyFirewall™ Engine API functions, namely MakeOffer, MakeAnswer and ProcessAnswer, are used to obtain an SDP description that includes the local ICE candidates, and parse the SDP description received from the remote SIP endpoint. The usage of these API functions is described in section 5. Code Examples for Windows, Linux, Mac, iOS of this guide and the sample application.

The integration of AnyFirewall™ Engine with media engines is described below.


Media Engine Integration

In order to integrate the AnyFirewall™ Engine with media engines, it is necessary to pass RTP packets received by AnyFirewall™ Engine to the media engine and to send RTP packets generated by the media engine to AnyFirewall™ Engine. Some media engines, such as TeamSpirt® Voice and Video Engine, also generate and process RTCP packets. In this case, the RTCP packets must also be sent and received via AnyFirewall™ Engine. Most media engines provide APIs to pass received RTP and RTCP packets to the media engine. In order to send RTP and RTCP packets generated by the media engine, callback functions are provided. These functions are called by the media engine and pass the RTP and RTCP data to the AnyFirewall™ Engine.
The process of sending and receiving media is outlined in section 5. Code Examples for Windows, Linux, Mac, iOS and the relevant source code is also available in the sample application.


Example: TeamSpirit® Voice and Video Engine - Sending

In order to use the AFE functions to send RTP and RTCP packets generated by TeamSpirit® Voice and Video Engine, the following callback function must be implemented:

void SPIRIT_STDCALL TS_Transport_SendPacket(void *pInst, TS_tePacketType PacketType, const void *pData, uint32 DataSize, TS_tChannelHandle Channel);

In order to use this function, an instance of the structure TSVoice_tChannelParams must be initialized as described below:


class CMyTransport {…};
CMyTransport myTransport;
TSVoice_tChannelParams ChannelParams;
…
ChannelParams .Transport.Type = ts_trans_external;
ChannelParams .Transport.Ext.SendData =  TS_Transport_SendPacket;
ChannelParams .Transport.Ext.Release = 0;
ChannelParams .Transport.Ext.pInst = &myTransport;
…

and then passed to the TeamSpirit® Voice and Video engine function

ts_error SPIRIT_STDCALL TSVoice_StartChannel(TS_tChannelHandle Channel, const TSVoice_tChannelParams *pParams);
This function is called for each voice channel.

The function TS_Transport_SendPacket simply needs to call the respective AnyFirewall™ Engine function Send as outlined in the following sample:

void SPIRIT_STDCALL TS_Transport_SendPacket(void *pInst, TS_tePacketType PacketType,
                    const void *pData,
                    uint32 DataSize,
                    TS_tChannelHandle Channel
                )
{
    CMyTransport* pTransport = (CMyTransport*)pInst;
    CAnyFirewallEngine* pMyAFE = pTransport->GetAFE();
    int iChannel = pTransport->GetChannelByHandle(Channel, PacketType);
    pMyAFE->Send(iChannel, pData, DataSize, AF_NON_BLOCKING);
}
For each voice channel generated in TeamSpirit® Voice and Video, two AnyFirewall™ Engine channels are required, one for RTP and one for RTCP packets.


Example: TeamSpirit® Voice and Video Engine - Receiving

RTP and RTCP packets received through the AnyFirewall™ Engine interface function Recv are passed on to TeamSpirit® Voice and Video Engine via the function call:

ts_error SPIRIT_STDCALL TSVoice_PushMediaPacket(TS_tChannelHandle Channel, TS_tePacketType PacketType, const void *pData, uint32 DataSize);

This can be done in a receiver function as outlined in the following sample code:

…
while (!stop)
{
    len = myAFE.Recv(RTPchannel, data, len, AF_BLOCKING);
    if (len > 0)
    {
        TSVoice_PushMediaPacket(channel[RTPchannel],ts_packet_rtp, data, len);
    }
}
…
…
while (!stop)
{
    len = myAFE.Recv(RTCPchannel, data, len, AF_BLOCKING);
    if (len > 0)
    {
        TSVoice_PushMediaPacket(channel[RTCPchannel], ts_packet_rtcp, data, len);
    }
}
…

In the receiving functions, it is necessary to distinguish channels created by TeamSpirt® Voice and Video Engine and AnyFirewall™ Engine channels and maintain them separately.


Example: Global IP Sound VoiceEngine™ - Sending

In order to use the AFE functions to send RTP and RTCP packets generated by Global IP Sound VoiceEngine™, the following class must be implemented:

class GIPS_transport
{
    public:
    virtual void SendPacket(int channel, const void *data, int len);
    virtual void SendRTCPPacket(int channel, const void *data,int len);
};
In order to use the functions of this class, an instance of the class is passed to the VoiceEngine™ function.
int GIPSVE_SetSendTransport(int channel, GIPS_transport&transport);
This function is called for each voice channel.

The functions SendPacket and SendRTCPPacket simply need to call the respective AnyFirewall™ Engine function Send as outlined in the following sample:

void GIPS_transport::SendPacket(int channel, const void *data, int len)
{
    myAFE.Send(RTPchannel[channel],data,len,AF_NON_BLOCKING);
}
void GIPS_transport::SendRTCPPacket(int channel, const void *data, int len)
{
    myAFE.Send(RTCPchannel[channel],data,len,AF_NON_BLOCKING);
}
For each voice channel generate in Global IP Sound VoiceEngine™, two AnyFirewall™ Engine channels are required, one for RTP and one for RTCP packets.


Example: Global IP Sound VoiceEngine™ - Receiving

RTP and RTCP packets received through the AnyFirewall™ Engine interface function Recv are passed on to Global IP Sound VoiceEngine™ via the two function calls:

int GIPSVE_ReceivedRTPPacket(int channel, const void *data, int len);
int GIPSVE_ReceivedRTCPPacket(int channel, const void *data, int len);

This can be done in a receiver function as outlined in the following sample code:

…
while (!stop)
{
    len = myAFE.Recv(RTPchannel,data,len,AF_BLOCKING);
    if (len>0)
    {
        GIPSVE_ReceivedRTPPacket(channel[RTPchannel],data,len);
    }
}
…
while (!stop)
{
    len = myAFE.Recv(RTCPchannel,data,len,AF_BLOCKING);
    if (len>0)
    {
        GIPSVE_ReceivedRTPPacket(channel[RTCPchannel],data,len);
    }
}
…
In the receiving functions, it is necessary to distinguish channels created by Global IP Sound VoiceEngine™ and AnyFirewall™ Engine channels and maintain them separately.