source/Sources/AirPlayReceiverSession.c
static OSStatus	_TimingSendRequest( AirPlayReceiverSessionRef inSession )
{
	OSStatus				err;
	AirTunesSource *		src;
	RTCPTimeSyncPacket		pkt;
	AirTunesTime			now;
	ssize_t					n;
	
	src = &inSession->source;
	
	// Build and send the request. The response is received asynchronously.
	
	pkt.v_p_m			= RTCPHeaderInsertVersion( 0, kRTPVersion );
	pkt.pt				= kRTCPTypeTimeSyncRequest;
	pkt.length			= htons( ( sizeof( pkt ) / 4 ) - 1 );
	pkt.rtpTimestamp	= 0;
	pkt.ntpOriginateHi	= 0;
	pkt.ntpOriginateLo	= 0;
	pkt.ntpReceiveHi	= 0;
	pkt.ntpReceiveLo	= 0;
	
	AirTunesClock_GetSynchronizedTime( inSession->airTunesClock, &now );
	src->rtcpTILastTransmitTimeHi = now.secs + kNTPvsUnixSeconds;
	src->rtcpTILastTransmitTimeLo = (uint32_t)( now.frac >> 32 );
	pkt.ntpTransmitHi	= htonl( src->rtcpTILastTransmitTimeHi );
	pkt.ntpTransmitLo	= htonl( src->rtcpTILastTransmitTimeLo );
	
	if( inSession->timingConnected )
	{
		n = send( inSession->timingSock, (char *) &pkt, sizeof( pkt ), 0 );
	}
	else
	{
		n = sendto( inSession->timingSock, (char *) &pkt, sizeof( pkt ), 0, &inSession->timingRemoteAddr.sa, 
			inSession->timingRemoteLen );
	}
	err = map_socket_value_errno( inSession->timingSock, n == (ssize_t) sizeof( pkt ), n );
	require_noerr_quiet( err, exit );
	increment_wrap( src->rtcpTISendCount, 1 );
	
exit:
	if( err ) atr_ulog( kLogLevelNotice, "### NTP send request failed: %#m\n", err );
	return( err );
}
//===========================================================================================================================
//	_TimingSendRequest
//
//	Note: This function does not need the AirTunes lock because it only accesses variables from a single thread at a time.
//		  These variables are only accessed once by the RTSP thread during init and then only by the timing thread.
//===========================================================================================================================
_TimingSendRequest
Note: This function does not need the AirTunes lock because it only accesses variables from a single thread at a time.
These variables are only accessed once by the RTSP thread during init and then only by the timing thread.
_TimingSendRequest Note : This function does not need the AirTunes lock because it only accesses variables from a single thread at a time . These variables are only accessed once by the RTSP thread during init and then only by the timing thread .
static OSStatus	_TimingSendRequest( AirPlayReceiverSessionRef inSession )
{
	OSStatus				err;
	AirTunesSource *		src;
	RTCPTimeSyncPacket		pkt;
	AirTunesTime			now;
	ssize_t					n;
	src = &inSession->source;
	pkt.v_p_m			= RTCPHeaderInsertVersion( 0, kRTPVersion );
	pkt.pt				= kRTCPTypeTimeSyncRequest;
	pkt.length			= htons( ( sizeof( pkt ) / 4 ) - 1 );
	pkt.rtpTimestamp	= 0;
	pkt.ntpOriginateHi	= 0;
	pkt.ntpOriginateLo	= 0;
	pkt.ntpReceiveHi	= 0;
	pkt.ntpReceiveLo	= 0;
	AirTunesClock_GetSynchronizedTime( inSession->airTunesClock, &now );
	src->rtcpTILastTransmitTimeHi = now.secs + kNTPvsUnixSeconds;
	src->rtcpTILastTransmitTimeLo = (uint32_t)( now.frac >> 32 );
	pkt.ntpTransmitHi	= htonl( src->rtcpTILastTransmitTimeHi );
	pkt.ntpTransmitLo	= htonl( src->rtcpTILastTransmitTimeLo );
	if( inSession->timingConnected )
	{
		n = send( inSession->timingSock, (char *) &pkt, sizeof( pkt ), 0 );
	}
	else
	{
		n = sendto( inSession->timingSock, (char *) &pkt, sizeof( pkt ), 0, &inSession->timingRemoteAddr.sa, 
			inSession->timingRemoteLen );
	}
	err = map_socket_value_errno( inSession->timingSock, n == (ssize_t) sizeof( pkt ), n );
	require_noerr_quiet( err, exit );
	increment_wrap( src->rtcpTISendCount, 1 );
exit:
	if( err ) atr_ulog( kLogLevelNotice, "### NTP send request failed: %#m\n", err );
	return( err );
}
static OSStatus _TimingSendRequest ( AirPlayReceiverSessionRef inSession ) { OSStatus err ; AirTunesSource * src ; RTCPTimeSyncPacket pkt ; AirTunesTime now ; ssize_t n ; src = & inSession -> source ; pkt . v_p_m = RTCPHeaderInsertVersion ( 0 , kRTPVersion ) ; pkt . pt = kRTCPTypeTimeSyncRequest ; pkt . length = htons ( ( sizeof ( pkt ) / 4 ) - 1 ) ; pkt . rtpTimestamp = 0 ; pkt . ntpOriginateHi = 0 ; pkt . ntpOriginateLo = 0 ; pkt . ntpReceiveHi = 0 ; pkt . ntpReceiveLo = 0 ; AirTunesClock_GetSynchronizedTime ( inSession -> airTunesClock , & now ) ; src -> rtcpTILastTransmitTimeHi = now . secs + kNTPvsUnixSeconds ; src -> rtcpTILastTransmitTimeLo = ( uint32_t ) ( now . frac >> 32 ) ; pkt . ntpTransmitHi = htonl ( src -> rtcpTILastTransmitTimeHi ) ; pkt . ntpTransmitLo = htonl ( src -> rtcpTILastTransmitTimeLo ) ; if ( inSession -> timingConnected ) { n = send ( inSession -> timingSock , ( char * ) & pkt , sizeof ( pkt ) , 0 ) ; } else { n = sendto ( inSession -> timingSock , ( char * ) & pkt , sizeof ( pkt ) , 0 , & inSession -> timingRemoteAddr . sa , inSession -> timingRemoteLen ) ; } err = map_socket_value_errno ( inSession -> timingSock , n == ( ssize_t ) sizeof ( pkt ) , n ) ; require_noerr_quiet ( err , exit ) ; increment_wrap ( src -> rtcpTISendCount , 1 ) ; exit : if ( err ) atr_ulog ( kLogLevelNotice , " \n " , err ) ; return ( err ) ; }
_TimingSendRequest
Note: This function does not need the AirTunes lock because it only accesses variables from a single thread at a time.
_TimingSendRequest Note : This function does not need the AirTunes lock because it only accesses variables from a single thread at a time .
// Build and send the request. The response is received asynchronously.