Receiving Media Directly from Socket

Some applications may prefer to send/receive media data directly from socket, instead of using the AFE Send/Recv API. AFE provides three functions to facilitate this:

  • GetSelectedSocket- the user application can get the selected socket descriptor of a channel after ICE checks are complete for the corresponding session (EAfEventCallCompletionStatusAvailable event). After this, the socket descriptor can be used to receive data using Berkeley socket API (select and recvfrom)
  • IsSTUNMessage- should be used for peer-to-peer cases. Checks if STUN/TURN packet, returns true if STUN/TURN packet and application should ignore that packet.
  • ProcessReceivedData - should be used for UDP Relay cases. The received data should be processed using this AFE function in order to handle any STUN/TURN packets.
  • DeleteUserData - any user data extracted with ProcessReceivedData must be freed with this function.


Please note that this mechanism is only applicable for media channels belonging to an ICE session. Also, when the call is UDP relay the socket may only be used for receiving data, not for sending data; data should be sent with the AFE Send API. For P2P and TCP-Relay (ICE-TCP) cases, the socket could be used for both sending and receiving data.
int GetSelectedSocket(int iChannel)
This function returns the socket descriptor of the selected candidate after ICE checks are complete. It may be called only after getting EAfEventCallCompletionStatusAvailable (EAfEventIceCheckCompleted event is always followed by EAfEventCallCompletionStatusAvailable for the relevant session). When the call is UDP relay, data directly received using the socket must be processed with ProcessReceivedData, so that STUN/TURN messages are used appropriately.


When TCP candidates are selected for media after ICE checks in Microsoft Lync mode, GetSelectedSocket will return the same socket descriptor for both RTP and RTCP channels because of multiplexing. In this case, the received data from the socket needs to be processed only once with the RTP channel (ProcessReceivedData).


Parameters:

int iChannelThe ID of the channel


Return value:

int The socket descriptor corresponding to the selected candidate after ICE checks. The returned value is negative in case of error.


This function returns the socket descriptor of the selected candidate after ICE checks are complete. It may be called only after getting EAfEventCallCompletionStatusAvailable (EAfEventIceCheckCompleted event is always followed by  EAfEventCallCompletionStatusAvailable  for the relevant session). The returned descriptor should only be used for receiving data, not for sending data. Data should be sent using the AFESend function. Data directly received using the socket must be processed with ProcessReceivedData, so that STUN/TURN messages are used appropriately.


When TCP candidates are selected for media after ICE checks in Microsoft® Lync™ mode, GetSelectedSocket will return the same socket descriptor for both RTP and RTCP channels because of multiplexing. In this case, the received data from the socket needs to be processed only once with the RTP channel (ProcessReceivedData).


Parameters:

int iChannelThe ID of the channel

Return value:

intThe socket descriptor corresponding to the selected candidate after ICE checks. The returned value is negative in case of error.


bool IsSTUNMessage(const char pBuffer[], int iLen)

This function is used to check keep-alive messages. It checks the data received directly with a socket descriptor which returned from GetSelectedSocket API. Note that, this method does not need be called if application sets channel option EAfOptionKeepAlivePeriodSeconds with value 0 or -1. Please see SetChannelOption() API documentation in Channel Management and Data Transfer.

Parameters:

int iLen
const char pBuffer[]Received data buffer.
Number of bytes written in data buffer.

Return value:

boolReturns true if STUN message is given as input, false otherwise.


int ProcessReceivedData(int iChannel, const char *pRawData, int nRawDataLen, const std::string& ipAddress, unsigned short uPort, struct UserData **ppUserData)
This function is used for processing the data received directly with a socket descriptor returned from GetSelectedSocket. Please disregard this API when the channel type is AF_CHANNEL_DATA or the application is using ICE-TCP.


Parameters:

int iChannel
The ID of the channel.
const char *pRawData
The buffer containing the raw data received from socket.
int nRawDataLen
The length of data in pRawData.
const std::string& ipAddress
The IP address of the source as reported by recvfrom.
unsigned short uPort
The port of the source as reported by recvfrom.
struct UserData **ppUserData
The address of a pointer to structUserData. Any user data extracted from TURN messages can be accessed with this pointer as the head of a linked list, after the function returns. The output parameter is described below: struct UserData { char *pData; int nDataLen; struct UserData *pNextUserData; }; pData is a pointer to the user data extracted from TURN packet. nDataLen is the length of the data. pNextUserData points to the next node in the linkedlist, with NULL indicating end of the list.


Return value:

int An integer indicating the result of processing:
* A negative value indicates error.
* Zero means data was found to be UDP user data. In this case, no modification is done by AFE and the data in pRawData can be directly used by the user. *ppUserData should be ignored.
* If the returned value is positive, it means data was found to be a STUN/TURN packet. User should make use of *ppUserData to read any user data extracted from the raw data. User should also free *ppUserData with DeleteUserData.


void DeleteUserData(struct UserData *pUserData)
This function is used for freeing the linked list returned by ProcessReceivedData.

Parameters:

struct UserData *pUserData The head of the linked list to be freed.