From 666cf82f4e8b2d3ddb6b09c9b9eefabf04bef45a Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Thu, 7 Mar 2024 12:49:19 -0800 Subject: [PATCH 01/11] Change params size --- .../kinesis/video/webrtcclient/Include.h | 5 ----- .../kinesis/video/webrtcclient/Stats.h | 21 +++++++++++++------ src/source/Ice/IceAgent.c | 13 +++++++----- src/source/Ice/IceAgent.h | 11 +++++----- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h index 232667c613..59569fb591 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h @@ -477,11 +477,6 @@ extern "C" { */ #define MAX_SIGNALING_ENDPOINT_URI_LEN 512 -/** - * Maximum allowed ICE URI length - */ -#define MAX_ICE_CONFIG_URI_LEN 256 - /** * Maximum allowed correlation ID length */ diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h index 72fffb67ba..6ab13c43c6 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h @@ -24,6 +24,11 @@ extern "C" { */ #define MAX_CANDIDATE_ID_LENGTH 9U +/** + * Maximum allowed ICE URI length + */ +#define MAX_ICE_CONFIG_URI_LEN 256 + /** * Maximum allowed relay protocol length */ @@ -63,6 +68,11 @@ extern "C" { * Maximum allowed generic length used in DOMString */ #define MAX_STATS_STRING_LENGTH 255U + +/** + * Maximum length of candidate type (host, srflx, relay, prflx, unknown) + */ +#define MAX_CANDIDATE_TYPE_LENGTH 10U /*!@} */ /** @@ -233,8 +243,8 @@ typedef struct { * Reference: https://www.w3.org/TR/webrtc-stats/#ice-server-dict* */ typedef struct { - DOMString url; //!< STUN/TURN server URL - DOMString protocol; //!< Valid values: UDP, TCP + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be //!< populated by the application to get specific server stats INT32 port; //!< Port number used by client @@ -268,14 +278,13 @@ typedef struct { typedef struct { DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - DOMString transportId; //!< Not used currently. ID of object that was inspected for RTCTransportStats CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate - DOMString protocol; //!< Valid values: UDP, TCP - DOMString relayProtocol; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) //!< Valid values: UDP, TCP, TLS INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 INT32 port; //!< Port number of the candidate - DOMString candidateType; //!< Type of local/remote ICE candidate + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate } RtcIceCandidateStats, *PRtcIceCandidateStats; /** diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 99f078288e..01c8031861 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -40,7 +40,11 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge CHK(NULL != (pIceAgent = (PIceAgent) MEMCALLOC(1, SIZEOF(IceAgent))), STATUS_NOT_ENOUGH_MEMORY); STRNCPY(pIceAgent->localUsername, username, MAX_ICE_CONFIG_USER_NAME_LEN); STRNCPY(pIceAgent->localPassword, password, MAX_ICE_CONFIG_CREDENTIAL_LEN); - + DLOGI("Size of RtcIceServerDiagnostics: %d", SIZEOF(RtcIceServerDiagnostics)); + DLOGI("Size of RtcIceCandidateDiagnostics: %d", SIZEOF(RtcIceCandidateDiagnostics)); + DLOGI("Size of IceAgentProfileDiagnostics: %d", SIZEOF(IceAgentProfileDiagnostics)); + DLOGI("Size of KvsIpAddress: %d", SIZEOF(KvsIpAddress)); + DLOGI("Size of ICE agent: %d", SIZEOF(IceAgent)); ATOMIC_STORE_BOOL(&pIceAgent->remoteCredentialReceived, FALSE); ATOMIC_STORE_BOOL(&pIceAgent->agentStartGathering, FALSE); ATOMIC_STORE_BOOL(&pIceAgent->candidateGatheringFinished, FALSE); @@ -88,7 +92,7 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge // Pre-allocate stun packets - // no other attributes needed: https://tools.ietf.org/html/rfc8445#section-11 + // no other attribtues needed: https://tools.ietf.org/html/rfc8445#section-11 CHK_STATUS(createStunPacket(STUN_PACKET_TYPE_BINDING_INDICATION, NULL, &pIceAgent->pBindingIndication)); CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceAgent->requestTimestampDiagnostics)); @@ -517,8 +521,7 @@ STATUS iceAgentAddRemoteCandidate(PIceAgent pIceAgent, PCHAR pIceCandidateString pLocalIceCandidate = (PIceCandidate) pCurNode->data; pCurNode = pCurNode->pNext; - // TODO: Remove IPv4 check once IPv6 TURN relay candidates are chosen. Disabling this to reduce the number of TURN permissions we create - if (pLocalIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && IS_IPV4_ADDR(&pLocalIceCandidate->ipAddress)) { + if (pLocalIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { CHK_STATUS(turnConnectionAddPeer(pLocalIceCandidate->pTurnConnection, &pIceCandidate->ipAddress)); } } @@ -675,7 +678,6 @@ STATUS iceAgentStartGathering(PIceAgent pIceAgent) ATOMIC_STORE_BOOL(&pIceAgent->agentStartGathering, TRUE); pIceAgent->candidateGatheringStartTime = GETTIME(); - // skip gathering host candidate and srflx candidate if relay only if (pIceAgent->iceTransportPolicy != ICE_TRANSPORT_POLICY_RELAY) { // Skip getting local host candidates if transport policy is relay only @@ -765,6 +767,7 @@ STATUS iceAgentSendPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen) packetsSent++; } + CleanUp: if (STATUS_SUCCEEDED(retStatus) && pIceAgent->pDataSendingIceCandidatePair != NULL) { diff --git a/src/source/Ice/IceAgent.h b/src/source/Ice/IceAgent.h index b692975c1b..0f82748485 100644 --- a/src/source/Ice/IceAgent.h +++ b/src/source/Ice/IceAgent.h @@ -80,8 +80,8 @@ typedef struct __IceAgent* PIceAgent; * Internal structure tracking ICE server parameters for diagnostics and metrics/stats */ typedef struct { - CHAR url[MAX_STATS_STRING_LENGTH + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_STATS_STRING_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP INT32 port; //!< Port number used by client UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server UINT64 totalResponsesReceived; //!< Total number of responses received from the server @@ -90,14 +90,13 @@ typedef struct { typedef struct { DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - DOMString transportId[MAX_STATS_STRING_LENGTH + 1]; //!< ID of object that was inspected for RTCTransportStats CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate - DOMString protocol; //!< Valid values: UDP, TCP - DOMString relayProtocol; //!< Protocol used by endpoint to communicate with TURN server. + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. //!< Valid values: UDP, TCP, TLS + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 INT32 port; //!< Port number of the candidate - DOMString candidateType; //!< Type of local/remote ICE candidate } RtcIceCandidateDiagnostics, *PRtcIceCandidateDiagnostics; typedef struct { From bf9a2ee4613bb94c07bc6fcccbcb550f16097afa Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Thu, 7 Mar 2024 14:33:15 -0800 Subject: [PATCH 02/11] Use dyanmic allocation and flag for ice stats --- samples/Common.c | 1 + .../kinesis/video/webrtcclient/Include.h | 1 + .../kinesis/video/webrtcclient/Stats.h | 34 +-- src/source/Ice/IceAgent.c | 231 +++++++++++------- src/source/Ice/IceAgent.h | 37 +-- src/source/Metrics/Metrics.c | 20 +- src/source/PeerConnection/PeerConnection.c | 2 - tst/MetricsApiTest.cpp | 3 +- 8 files changed, 198 insertions(+), 131 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index 33ee18b1e5..5d615ede9b 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -397,6 +397,7 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP // Set the ICE mode explicitly configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL; + configuration.kvsRtcConfiguration.enableIceStats = FALSE; // Set the STUN server PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h index 59569fb591..0676c5d095 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h @@ -1215,6 +1215,7 @@ typedef struct { BOOL disableSenderSideBandwidthEstimation; //!< Disable TWCC feedback based sender bandwidth estimation, enabled by default. //!< You want to set this to TRUE if you are on a very stable connection and want to save 1.2MB of //!< memory + BOOL enableIceStats; //!< Enable ICE stats to be calculated } KvsRtcConfiguration, *PKvsRtcConfiguration; /** diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h index 6ab13c43c6..ce03a869a8 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h @@ -72,7 +72,7 @@ extern "C" { /** * Maximum length of candidate type (host, srflx, relay, prflx, unknown) */ -#define MAX_CANDIDATE_TYPE_LENGTH 10U +#define MAX_CANDIDATE_TYPE_LENGTH 10U /*!@} */ /** @@ -243,14 +243,14 @@ typedef struct { * Reference: https://www.w3.org/TR/webrtc-stats/#ice-server-dict* */ typedef struct { - CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be - //!< populated by the application to get specific server stats - INT32 port; //!< Port number used by client - UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server - UINT64 totalResponsesReceived; //!< Total number of responses received from the server - UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be + //!< populated by the application to get specific server stats + INT32 port; //!< Port number used by client + UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server + UINT64 totalResponsesReceived; //!< Total number of responses received from the server + UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received } RtcIceServerStats, *PRtcIceServerStats; /** @@ -277,14 +277,14 @@ typedef struct { */ typedef struct { - DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) - //!< Valid values: UDP, TCP, TLS - INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 - INT32 port; //!< Port number of the candidate - CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate + DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained + CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) + //!< Valid values: UDP, TCP, TLS + INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 + INT32 port; //!< Port number of the candidate + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate } RtcIceCandidateStats, *PRtcIceCandidateStats; /** diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 01c8031861..c74be54e0d 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -81,6 +81,7 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge pIceAgent->pConnectionListener = pConnectionListener; pIceAgent->pDataSendingIceCandidatePair = NULL; pIceAgent->iceAgentState = ICE_AGENT_STATE_NEW; + pIceAgent->enableIceStats = pRtcConfiguration->kvsRtcConfiguration.enableIceStats; CHK_STATUS(createTransactionIdStore(DEFAULT_MAX_STORED_TRANSACTION_ID_COUNT, &pIceAgent->pStunBindingRequestTransactionIdStore)); pIceAgent->relayCandidateCount = 0; @@ -94,7 +95,6 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge // no other attribtues needed: https://tools.ietf.org/html/rfc8445#section-11 CHK_STATUS(createStunPacket(STUN_PACKET_TYPE_BINDING_INDICATION, NULL, &pIceAgent->pBindingIndication)); - CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceAgent->requestTimestampDiagnostics)); pIceAgent->iceServersCount = 0; for (i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { @@ -109,18 +109,22 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge (PCHAR) pRtcConfiguration->iceServers[i].username, (PCHAR) pRtcConfiguration->iceServers[i].credential), pIceAgent->iceAgentProfileDiagnostics.iceServerParsingTime[i], "ICE server parsing"); if (STATUS_SUCCEEDED(retStatus)) { - pIceAgent->rtcIceServerDiagnostics[i].port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); - switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { - case KVS_SOCKET_PROTOCOL_UDP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_UDP); - break; - case KVS_SOCKET_PROTOCOL_TCP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_TCP); - break; - default: - MEMSET(pIceAgent->rtcIceServerDiagnostics[i].protocol, 0, SIZEOF(pIceAgent->rtcIceServerDiagnostics[i].protocol)); + if (pIceAgent->enableIceStats) { + CHK(NULL != (pIceAgent->pRtcIceServerDiagnostics[i] = (PRtcIceServerDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceServerDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { + case KVS_SOCKET_PROTOCOL_UDP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); + break; + case KVS_SOCKET_PROTOCOL_TCP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_TCP); + break; + default: + MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); + } + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pRtcConfiguration->iceServers[i].urls); } - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].url, pRtcConfiguration->iceServers[i].urls); pIceAgent->iceServersCount++; } else { DLOGE("Failed to parse ICE servers"); @@ -128,6 +132,17 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge } } + if (pIceAgent->enableIceStats) { + CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceAgent->requestTimestampDiagnostics)); + CHK(NULL != + (pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics = + (PRtcIceCandidateDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidateDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + CHK(NULL != + (pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics = + (PRtcIceCandidateDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidateDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + } CleanUp: if (STATUS_FAILED(retStatus) && pIceAgent != NULL) { @@ -256,6 +271,12 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) freeTransactionIdStore(&pIceAgent->pStunBindingRequestTransactionIdStore); } + SAFE_MEMFREE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics); + SAFE_MEMFREE(pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics); + for (int i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { + SAFE_MEMFREE(pIceAgent->pRtcIceServerDiagnostics[i]); + } + MEMFREE(pIceAgent); *ppIceAgent = NULL; @@ -288,18 +309,21 @@ STATUS iceAgentAddConfig(PIceAgent pIceAgent, PIceConfigInfo pIceConfigInfo) if (STATUS_SUCCEEDED(retStatus)) { MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - pIceAgent->rtcIceServerDiagnostics[i].port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); - switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { - case KVS_SOCKET_PROTOCOL_UDP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_UDP); - break; - case KVS_SOCKET_PROTOCOL_TCP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_TCP); - break; - default: - MEMSET(pIceAgent->rtcIceServerDiagnostics[i].protocol, 0, SIZEOF(pIceAgent->rtcIceServerDiagnostics[i].protocol)); + if (pIceAgent->pRtcIceServerDiagnostics[i] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { + case KVS_SOCKET_PROTOCOL_UDP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); + break; + case KVS_SOCKET_PROTOCOL_TCP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_TCP); + break; + default: + MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); + } + + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pIceConfigInfo->uris[i]); } - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].url, pIceConfigInfo->uris[i]); MUTEX_UNLOCK(pIceAgent->lock); locked = FALSE; @@ -767,17 +791,18 @@ STATUS iceAgentSendPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen) packetsSent++; } - CleanUp: if (STATUS_SUCCEEDED(retStatus) && pIceAgent->pDataSendingIceCandidatePair != NULL) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.packetsDiscardedOnSend += packetsDiscarded; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesDiscardedOnSend += bytesDiscarded; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.state = pIceAgent->pDataSendingIceCandidatePair->state; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketSentTimestamp = - pIceAgent->pDataSendingIceCandidatePair->lastDataSentTime; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesSent += bytesSent; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.packetsSent += packetsSent; + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->packetsDiscardedOnSend += packetsDiscarded; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesDiscardedOnSend += bytesDiscarded; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->state = pIceAgent->pDataSendingIceCandidatePair->state; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp = + pIceAgent->pDataSendingIceCandidatePair->lastDataSentTime; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesSent += bytesSent; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->packetsSent += packetsSent; + } } if (locked) { @@ -1149,6 +1174,12 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, // pair local and remote candidates with the same family if (pCurrentIceCandidate->state == ICE_CANDIDATE_STATE_VALID && pCurrentIceCandidate->ipAddress.family == pIceCandidate->ipAddress.family) { pIceCandidatePair = (PIceCandidatePair) MEMCALLOC(1, SIZEOF(IceCandidatePair)); + if (pIceAgent->enableIceStats) { + CHK(NULL != + (pIceCandidatePair->pRtcIceCandidatePairDiagnostics = + (PRtcIceCandidatePairDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidatePairDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + } CHK(pIceCandidatePair != NULL, STATUS_NOT_ENOUGH_MEMORY); if (isRemoteCandidate) { @@ -1169,19 +1200,21 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceCandidatePair->requestSentTime)); pIceCandidatePair->lastDataSentTime = 0; - STRNCPY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.localCandidateId, pIceCandidatePair->local->id, - ARRAY_SIZE(pIceCandidatePair->rtcIceCandidatePairDiagnostics.localCandidateId)); - STRNCPY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.remoteCandidateId, pIceCandidatePair->remote->id, - ARRAY_SIZE(pIceCandidatePair->rtcIceCandidatePairDiagnostics.remoteCandidateId)); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.state = pIceCandidatePair->state; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketSentTimestamp = pIceCandidatePair->lastDataSentTime; + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + STRNCPY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->localCandidateId, pIceCandidatePair->local->id, + ARRAY_SIZE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->localCandidateId)); + STRNCPY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->remoteCandidateId, pIceCandidatePair->remote->id, + ARRAY_SIZE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->remoteCandidateId)); + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->state = pIceCandidatePair->state; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp = pIceCandidatePair->lastDataSentTime; + pIceCandidatePair->priority = computeCandidatePairPriority(pIceCandidatePair, pIceAgent->isControlling); + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->totalRoundTripTime = 0.0; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->currentRoundTripTime = 0.0; + // Set data sending ICE candidate pair stats + NULLABLE_SET_EMPTY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->circuitBreakerTriggerCount); + } pIceCandidatePair->firstStunRequest = TRUE; - pIceCandidatePair->priority = computeCandidatePairPriority(pIceCandidatePair, pIceAgent->isControlling); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.totalRoundTripTime = 0.0; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.currentRoundTripTime = 0.0; - // Set data sending ICE candidate pair stats - NULLABLE_SET_EMPTY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.circuitBreakerTriggerCount); CHK_STATUS(insertIceCandidatePair(pIceAgent->iceCandidatePairs, pIceCandidatePair)); freeObjOnFailure = FALSE; } @@ -1210,6 +1243,7 @@ STATUS freeIceCandidatePair(PIceCandidatePair* ppIceCandidatePair) CHK(*ppIceCandidatePair != NULL, retStatus); pIceCandidatePair = *ppIceCandidatePair; + SAFE_MEMFREE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics); CHK_LOG_ERR(freeTransactionIdStore(&pIceCandidatePair->pTransactionIdStore)); CHK_LOG_ERR(hashTableFree(pIceCandidatePair->requestSentTime)); SAFE_MEMFREE(pIceCandidatePair); @@ -1353,18 +1387,23 @@ STATUS iceCandidatePairCheckConnection(PStunPacket pStunBindingRequest, PIceAgen transactionIdStoreInsert(pIceCandidatePair->pTransactionIdStore, pStunBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pStunBindingRequest->header.transactionId, ARRAY_SIZE(pStunBindingRequest->header.transactionId)); CHK_STATUS(hashTableUpsert(pIceCandidatePair->requestSentTime, checkSum, GETTIME())); - CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + if (pIceAgent->requestTimestampDiagnostics != NULL) { + CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + } - if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRequestsSent++; + if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalRequestsSent++; } CHK_STATUS(iceAgentSendStunPacket(pStunBindingRequest, (PBYTE) pIceAgent->remotePassword, (UINT32) STRLEN(pIceAgent->remotePassword) * SIZEOF(CHAR), pIceAgent, pIceCandidatePair->local, &pIceCandidatePair->remote->ipAddress)); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastRequestTimestamp = GETTIME(); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.requestsSent++; + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastRequestTimestamp = GETTIME(); + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->requestsSent++; + } CleanUp: CHK_LOG_ERR(retStatus); @@ -1409,7 +1448,9 @@ STATUS iceAgentSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa &pIceCandidatePair)); if (pIceCandidatePair != NULL && pIceCandidatePair == pIceAgent->pDataSendingIceCandidatePair && pIceAgent->pDataSendingIceCandidatePair->firstStunRequest) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.firstRequestTimestamp = GETTIME(); + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->firstRequestTimestamp = GETTIME(); + } pIceAgent->pDataSendingIceCandidatePair->firstStunRequest = FALSE; } } @@ -1489,8 +1530,10 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddress)); - pIceAgent->rtcIceServerDiagnostics[pCandidate->iceServerIndex].totalRequestsSent++; - CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex]->totalRequestsSent++; + CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + } } break; @@ -2041,10 +2084,12 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) STATUS retStatus = STATUS_SUCCESS; CHK(pIceAgent != NULL && pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_NULL_ARG); PIceCandidate pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->remote; - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedRemoteIceCandidateDiagnostics; + + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; + CHK(pRtcIceCandidateDiagnostics != NULL, STATUS_SUCCESS); if (!isRemote) { pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->local; - pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedLocalIceCandidateDiagnostics; + pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; STRNCPY(pRtcIceCandidateDiagnostics->url, STATS_NOT_APPLICABLE_STR, ARRAY_SIZE(pRtcIceCandidateDiagnostics->url)); // URL and relay protocol are populated only for local candidate by spec. // If candidate type is host, there is no URL and is set to N/A @@ -2063,7 +2108,7 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) break; case KVS_SOCKET_PROTOCOL_TCP: STRNCPY(pRtcIceCandidateDiagnostics->relayProtocol, ICE_TRANSPORT_TYPE_TCP, - ARRAY_SIZE(pIceAgent->rtcSelectedLocalIceCandidateDiagnostics.relayProtocol)); + ARRAY_SIZE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics->relayProtocol)); break; default: MEMSET(pRtcIceCandidateDiagnostics->relayProtocol, 0, SIZEOF(pRtcIceCandidateDiagnostics->relayProtocol)); @@ -2077,8 +2122,8 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) ARRAY_SIZE(pRtcIceCandidateDiagnostics->candidateType)); STRNCPY(pRtcIceCandidateDiagnostics->protocol, ICE_TRANSPORT_TYPE_UDP, ARRAY_SIZE(pRtcIceCandidateDiagnostics->protocol)); - if (pIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { - STRNCPY(pRtcIceCandidateDiagnostics->protocol, pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].protocol, + if (pIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex] != NULL) { + STRNCPY(pRtcIceCandidateDiagnostics->protocol, pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->protocol, ARRAY_SIZE(pRtcIceCandidateDiagnostics->protocol)); } CleanUp: @@ -2241,7 +2286,9 @@ STATUS iceAgentReadyStateSetup(PIceAgent pIceAgent) pCurNode = pCurNode->pNext; if (pIceCandidatePair->nominated && pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { pNominatedAndValidCandidatePair = pIceCandidatePair; - pNominatedAndValidCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; + if (pNominatedAndValidCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pNominatedAndValidCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; + } break; } } @@ -2447,10 +2494,12 @@ STATUS incomingDataHandler(UINT64 customData, PSocketConnection pSocketConnectio pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.family == pSrc->family && MEMCMP(pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.address, pSrc->address, addrLen) == 0 && (pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.port == pSrc->port)) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketReceivedTimestamp = GETTIME(); - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesReceived += bufferLen; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics - .packetsReceived++; // Since every byte buffer translates to a single RTP packet + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketReceivedTimestamp = GETTIME(); + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesReceived += bufferLen; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics + ->packetsReceived++; // Since every byte buffer translates to a single RTP packet + } } } else { if (ATOMIC_LOAD_BOOL(&pIceAgent->processStun)) { @@ -2581,9 +2630,11 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } if (pIceCandidatePair == pIceAgent->pDataSendingIceCandidatePair) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.requestsReceived += connectivityCheckRequestsReceived; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.responsesSent += connectivityCheckResponsesSent; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->requestsReceived += connectivityCheckRequestsReceived; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->responsesSent += connectivityCheckResponsesSent; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; + } } else { DLOGD("going to change the data sending ice candidate pair."); } @@ -2599,13 +2650,15 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pSocketConnection->localSocket); // Update round trip time for serial reflexive candidate - pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalResponsesReceived++; - // Transaction ID count be same for candidates coming from same interface, which means there would only - // be one entry. It is not necessary to update a return sttaus since it is not indicative of a failure - if ((hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime)) == STATUS_SUCCESS) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; - CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); - hashTableGetCount(pIceAgent->requestTimestampDiagnostics, &count); + if (pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->totalResponsesReceived++; + // Transaction ID count be same for candidates coming from same interface, which means there would only + // be one entry. It is not necessary to update a return sttaus since it is not indicative of a failure + if ((hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime)) == STATUS_SUCCESS) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->totalRoundTripTime += GETTIME() - requestSentTime; + CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); + hashTableGetCount(pIceAgent->requestTimestampDiagnostics, &count); + } } CHK_STATUS(deserializeStunPacket(pBuffer, bufferLen, NULL, 0, &pStunPacket)); @@ -2631,22 +2684,28 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS ipAddrStr2, ipAddrStr); } DLOGD("Pair binding response! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); - if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { - pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.currentRoundTripTime = - (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; - } else { - DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { + pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->currentRoundTripTime = + (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + } + } else { + DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); + } } + CHK_WARN(transactionIdStoreHasId(pIceCandidatePair->pTransactionIdStore, pBuffer + STUN_PACKET_TRANSACTION_ID_OFFSET), retStatus, "Dropping response packet because transaction id does not match"); // Update round trip time and responses received only for relay candidates. - if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalResponsesReceived++; + if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalResponsesReceived++; retStatus = hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime); if (hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime) == STATUS_SUCCESS) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalRoundTripTime += GETTIME() - requestSentTime; CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); } } @@ -2679,8 +2738,10 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; DLOGD("Ice candidate pair %s_%s is connected. Round trip time: %" PRIu64 "ms", pIceCandidatePair->local->id, pIceCandidatePair->remote->id, pIceCandidatePair->roundTripTime / HUNDREDS_OF_NANOS_IN_A_MILLISECOND); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.totalRoundTripTime += - (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->totalRoundTripTime += + (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + } CHK_STATUS(hashTableRemove(pIceCandidatePair->requestSentTime, checkSum)); } else { @@ -2688,8 +2749,10 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } } - pIceCandidatePair->rtcIceCandidatePairDiagnostics.responsesReceived += connectivityCheckResponsesReceived; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastResponseTimestamp = GETTIME(); + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->responsesReceived += connectivityCheckResponsesReceived; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastResponseTimestamp = GETTIME(); + } break; case STUN_PACKET_TYPE_BINDING_INDICATION: diff --git a/src/source/Ice/IceAgent.h b/src/source/Ice/IceAgent.h index 0f82748485..778ba6e9b7 100644 --- a/src/source/Ice/IceAgent.h +++ b/src/source/Ice/IceAgent.h @@ -80,23 +80,23 @@ typedef struct __IceAgent* PIceAgent; * Internal structure tracking ICE server parameters for diagnostics and metrics/stats */ typedef struct { - CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - INT32 port; //!< Port number used by client - UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server - UINT64 totalResponsesReceived; //!< Total number of responses received from the server - UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + INT32 port; //!< Port number used by client + UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server + UINT64 totalResponsesReceived; //!< Total number of responses received from the server + UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received } RtcIceServerDiagnostics, *PRtcIceServerDiagnostics; typedef struct { - DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. - //!< Valid values: UDP, TCP, TLS - CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate - INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 - INT32 port; //!< Port number of the candidate + DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained + CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. + //!< Valid values: UDP, TCP, TLS + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate + INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 + INT32 port; //!< Port number of the candidate } RtcIceCandidateDiagnostics, *PRtcIceCandidateDiagnostics; typedef struct { @@ -182,7 +182,7 @@ typedef struct { PHashTable requestSentTime; UINT64 roundTripTime; UINT64 responsesReceived; - RtcIceCandidatePairDiagnostics rtcIceCandidatePairDiagnostics; + PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics; } IceCandidatePair, *PIceCandidatePair; typedef struct { @@ -210,9 +210,9 @@ struct __IceAgent { CHAR remotePassword[MAX_ICE_CONFIG_CREDENTIAL_LEN + 1]; CHAR combinedUserName[(MAX_ICE_CONFIG_USER_NAME_LEN + 1) << 1]; //!< the combination of remote user name and local user name. - RtcIceServerDiagnostics rtcIceServerDiagnostics[MAX_ICE_SERVERS_COUNT]; - RtcIceCandidateDiagnostics rtcSelectedLocalIceCandidateDiagnostics; - RtcIceCandidateDiagnostics rtcSelectedRemoteIceCandidateDiagnostics; + PRtcIceServerDiagnostics pRtcIceServerDiagnostics[MAX_ICE_SERVERS_COUNT]; + PRtcIceCandidateDiagnostics pRtcSelectedLocalIceCandidateDiagnostics; + PRtcIceCandidateDiagnostics pRtcSelectedRemoteIceCandidateDiagnostics; IceAgentProfileDiagnostics iceAgentProfileDiagnostics; PHashTable requestTimestampDiagnostics; @@ -273,6 +273,7 @@ struct __IceAgent { UINT64 candidateGatheringStartTime; UINT64 candidateGatheringProcessEndTime; UINT64 iceAgentStartTime; + BOOL enableIceStats; }; ////////////////////////////////////////////// diff --git a/src/source/Metrics/Metrics.c b/src/source/Metrics/Metrics.c index f39c3e0292..bddcc74d8b 100644 --- a/src/source/Metrics/Metrics.c +++ b/src/source/Metrics/Metrics.c @@ -14,7 +14,8 @@ STATUS getIceCandidatePairStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceCa MUTEX_LOCK(pIceAgent->lock); locked = TRUE; CHK(pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_SUCCESS); - PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = &pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics; + PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics; + CHK_WARN(pRtcIceCandidatePairDiagnostics != NULL, STATUS_NULL_ARG, "Candidate pair not populated"); STRCPY(pRtcIceCandidatePairStats->localCandidateId, pRtcIceCandidatePairDiagnostics->localCandidateId); STRCPY(pRtcIceCandidatePairStats->remoteCandidateId, pRtcIceCandidatePairDiagnostics->remoteCandidateId); pRtcIceCandidatePairStats->state = pRtcIceCandidatePairDiagnostics->state; @@ -59,9 +60,10 @@ STATUS getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote CHK((pRtcPeerConnection != NULL || pRtcIceCandidateStats != NULL), STATUS_NULL_ARG); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedRemoteIceCandidateDiagnostics; + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; + CHK_WARN(pRtcIceCandidateDiagnostics != NULL, STATUS_NULL_ARG, "Candidate stats not populated"); if (!isRemote) { - pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedLocalIceCandidateDiagnostics; + pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; STRCPY(pRtcIceCandidateStats->relayProtocol, pRtcIceCandidateDiagnostics->relayProtocol); STRCPY(pRtcIceCandidateStats->url, pRtcIceCandidateDiagnostics->url); } @@ -87,12 +89,12 @@ STATUS getIceServerStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceServerSta MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - pRtcIceServerStats->port = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].port; - STRCPY(pRtcIceServerStats->protocol, pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].protocol); - STRCPY(pRtcIceServerStats->url, pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].url); - pRtcIceServerStats->totalRequestsSent = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalRequestsSent; - pRtcIceServerStats->totalResponsesReceived = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalResponsesReceived; - pRtcIceServerStats->totalRoundTripTime = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalRoundTripTime; + pRtcIceServerStats->port = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->port; + STRCPY(pRtcIceServerStats->protocol, pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->protocol); + STRCPY(pRtcIceServerStats->url, pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->url); + pRtcIceServerStats->totalRequestsSent = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalRequestsSent; + pRtcIceServerStats->totalResponsesReceived = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalResponsesReceived; + pRtcIceServerStats->totalRoundTripTime = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalRoundTripTime; CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index 4ea9f8153c..f02d55e897 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -341,11 +341,9 @@ STATUS changePeerConnectionState(PKvsPeerConnection pKvsPeerConnection, RTC_PEER customData = pKvsPeerConnection->onConnectionStateChangeCustomData; MUTEX_UNLOCK(pKvsPeerConnection->peerConnectionObjLock); locked = FALSE; - if (onConnectionStateChange != NULL) { onConnectionStateChange(customData, newState); } - CleanUp: if (locked) { diff --git a/tst/MetricsApiTest.cpp b/tst/MetricsApiTest.cpp index 7484d2db94..2141ebaf8a 100644 --- a/tst/MetricsApiTest.cpp +++ b/tst/MetricsApiTest.cpp @@ -56,6 +56,7 @@ TEST_F(MetricsApiTest, webRtcIceServerGetMetrics) STRNCPY(configuration.iceServers[1].urls, (PCHAR) "turns:54.202.170.151:443?transport=tcp", MAX_ICE_CONFIG_URI_LEN); STRNCPY(configuration.iceServers[1].credential, (PCHAR) "username", MAX_ICE_CONFIG_CREDENTIAL_LEN); STRNCPY(configuration.iceServers[1].username, (PCHAR) "password", MAX_ICE_CONFIG_USER_NAME_LEN); + configuration.kvsRtcConfiguration.enableIceStats = TRUE; ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); @@ -89,7 +90,7 @@ TEST_F(MetricsApiTest, webRtcIceCandidateGetMetrics) STRNCPY(configuration.iceServers[0].urls, (PCHAR) "stun:stun.kinesisvideo.us-west-2.amazonaws.com:443", MAX_ICE_CONFIG_URI_LEN); STRNCPY(configuration.iceServers[0].credential, (PCHAR) "", MAX_ICE_CONFIG_CREDENTIAL_LEN); STRNCPY(configuration.iceServers[0].username, (PCHAR) "", MAX_ICE_CONFIG_USER_NAME_LEN); - + configuration.kvsRtcConfiguration.enableIceStats = TRUE; ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); pIceAgent = ((PKvsPeerConnection) pRtcPeerConnection)->pIceAgent; From ad7d02f10b3bb153640b38b0f0722eef902a9434 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Thu, 7 Mar 2024 15:40:04 -0800 Subject: [PATCH 03/11] Debug 1 --- samples/Common.c | 26 +++++++++++++------------- src/source/Ice/IceAgent.c | 13 ++++++------- src/source/Metrics/Metrics.c | 4 ++++ 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index 5d615ede9b..1e90f8c994 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -114,21 +114,21 @@ STATUS logSelectedIceCandidatesInformation(PSampleStreamingSession pSampleStream CHK(pSampleStreamingSession != NULL, STATUS_NULL_ARG); rtcMetrics.requestedTypeOfStats = RTC_STATS_TYPE_LOCAL_CANDIDATE; CHK_STATUS(rtcPeerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, NULL, &rtcMetrics)); - DLOGD("Local Candidate IP Address: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.address); - DLOGD("Local Candidate type: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.candidateType); - DLOGD("Local Candidate port: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.port); - DLOGD("Local Candidate priority: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.priority); - DLOGD("Local Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.protocol); - DLOGD("Local Candidate relay protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.relayProtocol); - DLOGD("Local Candidate Ice server source: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.url); + DLOGI("Local Candidate IP Address: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.address); + DLOGI("Local Candidate type: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.candidateType); + DLOGI("Local Candidate port: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.port); + DLOGI("Local Candidate priority: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.priority); + DLOGI("Local Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.protocol); + DLOGI("Local Candidate relay protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.relayProtocol); + DLOGI("Local Candidate Ice server source: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.url); rtcMetrics.requestedTypeOfStats = RTC_STATS_TYPE_REMOTE_CANDIDATE; CHK_STATUS(rtcPeerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, NULL, &rtcMetrics)); - DLOGD("Remote Candidate IP Address: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.address); - DLOGD("Remote Candidate type: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.candidateType); - DLOGD("Remote Candidate port: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.port); - DLOGD("Remote Candidate priority: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.priority); - DLOGD("Remote Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.protocol); + DLOGI("Remote Candidate IP Address: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.address); + DLOGI("Remote Candidate type: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.candidateType); + DLOGI("Remote Candidate port: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.port); + DLOGI("Remote Candidate priority: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.priority); + DLOGI("Remote Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.protocol); CleanUp: LEAVES(); return retStatus; @@ -397,8 +397,8 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP // Set the ICE mode explicitly configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL; - configuration.kvsRtcConfiguration.enableIceStats = FALSE; + configuration.kvsRtcConfiguration.enableIceStats = TRUE; // Set the STUN server PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; // If region is in CN, add CN region uri postfix diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index c74be54e0d..dced4533d1 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -180,8 +180,6 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) pIceAgent = *ppIceAgent; - hashTableFree(pIceAgent->requestTimestampDiagnostics); - if (pIceAgent->localCandidates != NULL) { CHK_STATUS(doubleListGetHeadNode(pIceAgent->localCandidates, &pCurNode)); while (pCurNode != NULL) { @@ -276,6 +274,7 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) for (int i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { SAFE_MEMFREE(pIceAgent->pRtcIceServerDiagnostics[i]); } + hashTableFree(pIceAgent->requestTimestampDiagnostics); MEMFREE(pIceAgent); @@ -2084,7 +2083,6 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) STATUS retStatus = STATUS_SUCCESS; CHK(pIceAgent != NULL && pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_NULL_ARG); PIceCandidate pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->remote; - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; CHK(pRtcIceCandidateDiagnostics != NULL, STATUS_SUCCESS); if (!isRemote) { @@ -2179,16 +2177,17 @@ STATUS iceAgentConnectedStateSetup(PIceAgent pIceAgent) MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - // use the first connected pair as the data sending pair CHK_STATUS(doubleListGetHeadNode(pIceAgent->iceCandidatePairs, &pCurNode)); while (pCurNode != NULL) { pIceCandidatePair = (PIceCandidatePair) pCurNode->data; pCurNode = pCurNode->pNext; - + DLOGI("Connected state...%d, %d", pIceCandidatePair->state, pIceCandidatePair->nominated); if (pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED && pIceCandidatePair->nominated) { pIceAgent->pDataSendingIceCandidatePair = pIceCandidatePair; + DLOGI("Here after selection"); retStatus = updateSelectedLocalRemoteCandidateStats(pIceAgent); + DLOGI("Here after updating stats"); if (STATUS_FAILED(retStatus)) { DLOGW("Failed to update candidate stats with status code 0x%08x", retStatus); } @@ -2616,7 +2615,7 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS if (!pIceCandidatePair->nominated) { CHK_STATUS(getStunAttribute(pStunPacket, STUN_ATTRIBUTE_TYPE_USE_CANDIDATE, &pStunAttr)); if (pStunAttr != NULL) { - DLOGD("received candidate with USE_CANDIDATE flag, local candidate type %s(%s:%s).", + DLOGI("received candidate with USE_CANDIDATE flag, local candidate type %s(%s:%s).", iceAgentGetCandidateTypeStr(pIceCandidatePair->local->iceCandidateType), pIceCandidatePair->local->id, pIceCandidatePair->remote->id); pIceCandidatePair->nominated = TRUE; @@ -2731,7 +2730,7 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } if (pIceCandidatePair->state != ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { - DLOGD("Pair succeeded! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); + DLOGI("Pair succeeded! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); pIceCandidatePair->state = ICE_CANDIDATE_PAIR_STATE_SUCCEEDED; retStatus = hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime); if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { diff --git a/src/source/Metrics/Metrics.c b/src/source/Metrics/Metrics.c index bddcc74d8b..2548430f4c 100644 --- a/src/source/Metrics/Metrics.c +++ b/src/source/Metrics/Metrics.c @@ -60,18 +60,22 @@ STATUS getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote CHK((pRtcPeerConnection != NULL || pRtcIceCandidateStats != NULL), STATUS_NULL_ARG); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; + DLOGI("Here"); PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; CHK_WARN(pRtcIceCandidateDiagnostics != NULL, STATUS_NULL_ARG, "Candidate stats not populated"); if (!isRemote) { + DLOGI("Here1"); pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; STRCPY(pRtcIceCandidateStats->relayProtocol, pRtcIceCandidateDiagnostics->relayProtocol); STRCPY(pRtcIceCandidateStats->url, pRtcIceCandidateDiagnostics->url); } + DLOGI("Here2"); STRCPY(pRtcIceCandidateStats->address, pRtcIceCandidateDiagnostics->address); STRCPY(pRtcIceCandidateStats->candidateType, pRtcIceCandidateDiagnostics->candidateType); pRtcIceCandidateStats->port = pRtcIceCandidateDiagnostics->port; pRtcIceCandidateStats->priority = pRtcIceCandidateDiagnostics->priority; STRCPY(pRtcIceCandidateStats->protocol, pRtcIceCandidateDiagnostics->protocol); + DLOGI("Here3"); CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); From 5ddcf3cd41a66c8f184220c38da9ce876b3bbc65 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Fri, 8 Mar 2024 13:07:57 -0800 Subject: [PATCH 04/11] Revert "Debug 1" This reverts commit ad7d02f10b3bb153640b38b0f0722eef902a9434. --- samples/Common.c | 26 +++++++++++++------------- src/source/Ice/IceAgent.c | 13 +++++++------ src/source/Metrics/Metrics.c | 4 ---- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index 1e90f8c994..5d615ede9b 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -114,21 +114,21 @@ STATUS logSelectedIceCandidatesInformation(PSampleStreamingSession pSampleStream CHK(pSampleStreamingSession != NULL, STATUS_NULL_ARG); rtcMetrics.requestedTypeOfStats = RTC_STATS_TYPE_LOCAL_CANDIDATE; CHK_STATUS(rtcPeerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, NULL, &rtcMetrics)); - DLOGI("Local Candidate IP Address: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.address); - DLOGI("Local Candidate type: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.candidateType); - DLOGI("Local Candidate port: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.port); - DLOGI("Local Candidate priority: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.priority); - DLOGI("Local Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.protocol); - DLOGI("Local Candidate relay protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.relayProtocol); - DLOGI("Local Candidate Ice server source: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.url); + DLOGD("Local Candidate IP Address: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.address); + DLOGD("Local Candidate type: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.candidateType); + DLOGD("Local Candidate port: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.port); + DLOGD("Local Candidate priority: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.priority); + DLOGD("Local Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.protocol); + DLOGD("Local Candidate relay protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.relayProtocol); + DLOGD("Local Candidate Ice server source: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.url); rtcMetrics.requestedTypeOfStats = RTC_STATS_TYPE_REMOTE_CANDIDATE; CHK_STATUS(rtcPeerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, NULL, &rtcMetrics)); - DLOGI("Remote Candidate IP Address: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.address); - DLOGI("Remote Candidate type: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.candidateType); - DLOGI("Remote Candidate port: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.port); - DLOGI("Remote Candidate priority: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.priority); - DLOGI("Remote Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.protocol); + DLOGD("Remote Candidate IP Address: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.address); + DLOGD("Remote Candidate type: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.candidateType); + DLOGD("Remote Candidate port: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.port); + DLOGD("Remote Candidate priority: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.priority); + DLOGD("Remote Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.protocol); CleanUp: LEAVES(); return retStatus; @@ -397,8 +397,8 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP // Set the ICE mode explicitly configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL; + configuration.kvsRtcConfiguration.enableIceStats = FALSE; - configuration.kvsRtcConfiguration.enableIceStats = TRUE; // Set the STUN server PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; // If region is in CN, add CN region uri postfix diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index dced4533d1..c74be54e0d 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -180,6 +180,8 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) pIceAgent = *ppIceAgent; + hashTableFree(pIceAgent->requestTimestampDiagnostics); + if (pIceAgent->localCandidates != NULL) { CHK_STATUS(doubleListGetHeadNode(pIceAgent->localCandidates, &pCurNode)); while (pCurNode != NULL) { @@ -274,7 +276,6 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) for (int i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { SAFE_MEMFREE(pIceAgent->pRtcIceServerDiagnostics[i]); } - hashTableFree(pIceAgent->requestTimestampDiagnostics); MEMFREE(pIceAgent); @@ -2083,6 +2084,7 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) STATUS retStatus = STATUS_SUCCESS; CHK(pIceAgent != NULL && pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_NULL_ARG); PIceCandidate pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->remote; + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; CHK(pRtcIceCandidateDiagnostics != NULL, STATUS_SUCCESS); if (!isRemote) { @@ -2177,17 +2179,16 @@ STATUS iceAgentConnectedStateSetup(PIceAgent pIceAgent) MUTEX_LOCK(pIceAgent->lock); locked = TRUE; + // use the first connected pair as the data sending pair CHK_STATUS(doubleListGetHeadNode(pIceAgent->iceCandidatePairs, &pCurNode)); while (pCurNode != NULL) { pIceCandidatePair = (PIceCandidatePair) pCurNode->data; pCurNode = pCurNode->pNext; - DLOGI("Connected state...%d, %d", pIceCandidatePair->state, pIceCandidatePair->nominated); + if (pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED && pIceCandidatePair->nominated) { pIceAgent->pDataSendingIceCandidatePair = pIceCandidatePair; - DLOGI("Here after selection"); retStatus = updateSelectedLocalRemoteCandidateStats(pIceAgent); - DLOGI("Here after updating stats"); if (STATUS_FAILED(retStatus)) { DLOGW("Failed to update candidate stats with status code 0x%08x", retStatus); } @@ -2615,7 +2616,7 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS if (!pIceCandidatePair->nominated) { CHK_STATUS(getStunAttribute(pStunPacket, STUN_ATTRIBUTE_TYPE_USE_CANDIDATE, &pStunAttr)); if (pStunAttr != NULL) { - DLOGI("received candidate with USE_CANDIDATE flag, local candidate type %s(%s:%s).", + DLOGD("received candidate with USE_CANDIDATE flag, local candidate type %s(%s:%s).", iceAgentGetCandidateTypeStr(pIceCandidatePair->local->iceCandidateType), pIceCandidatePair->local->id, pIceCandidatePair->remote->id); pIceCandidatePair->nominated = TRUE; @@ -2730,7 +2731,7 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } if (pIceCandidatePair->state != ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { - DLOGI("Pair succeeded! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); + DLOGD("Pair succeeded! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); pIceCandidatePair->state = ICE_CANDIDATE_PAIR_STATE_SUCCEEDED; retStatus = hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime); if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { diff --git a/src/source/Metrics/Metrics.c b/src/source/Metrics/Metrics.c index 2548430f4c..bddcc74d8b 100644 --- a/src/source/Metrics/Metrics.c +++ b/src/source/Metrics/Metrics.c @@ -60,22 +60,18 @@ STATUS getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote CHK((pRtcPeerConnection != NULL || pRtcIceCandidateStats != NULL), STATUS_NULL_ARG); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - DLOGI("Here"); PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; CHK_WARN(pRtcIceCandidateDiagnostics != NULL, STATUS_NULL_ARG, "Candidate stats not populated"); if (!isRemote) { - DLOGI("Here1"); pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; STRCPY(pRtcIceCandidateStats->relayProtocol, pRtcIceCandidateDiagnostics->relayProtocol); STRCPY(pRtcIceCandidateStats->url, pRtcIceCandidateDiagnostics->url); } - DLOGI("Here2"); STRCPY(pRtcIceCandidateStats->address, pRtcIceCandidateDiagnostics->address); STRCPY(pRtcIceCandidateStats->candidateType, pRtcIceCandidateDiagnostics->candidateType); pRtcIceCandidateStats->port = pRtcIceCandidateDiagnostics->port; pRtcIceCandidateStats->priority = pRtcIceCandidateDiagnostics->priority; STRCPY(pRtcIceCandidateStats->protocol, pRtcIceCandidateDiagnostics->protocol); - DLOGI("Here3"); CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); From 08f0ac7a4c9b65c5ff7cbc9ef14e9a5bad085614 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Fri, 8 Mar 2024 13:08:05 -0800 Subject: [PATCH 05/11] Revert "Use dyanmic allocation and flag for ice stats" This reverts commit bf9a2ee4613bb94c07bc6fcccbcb550f16097afa. --- samples/Common.c | 1 - .../kinesis/video/webrtcclient/Include.h | 1 - .../kinesis/video/webrtcclient/Stats.h | 34 +-- src/source/Ice/IceAgent.c | 231 +++++++----------- src/source/Ice/IceAgent.h | 37 ++- src/source/Metrics/Metrics.c | 20 +- src/source/PeerConnection/PeerConnection.c | 2 + tst/MetricsApiTest.cpp | 3 +- 8 files changed, 131 insertions(+), 198 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index 5d615ede9b..33ee18b1e5 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -397,7 +397,6 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP // Set the ICE mode explicitly configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL; - configuration.kvsRtcConfiguration.enableIceStats = FALSE; // Set the STUN server PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h index 0676c5d095..59569fb591 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h @@ -1215,7 +1215,6 @@ typedef struct { BOOL disableSenderSideBandwidthEstimation; //!< Disable TWCC feedback based sender bandwidth estimation, enabled by default. //!< You want to set this to TRUE if you are on a very stable connection and want to save 1.2MB of //!< memory - BOOL enableIceStats; //!< Enable ICE stats to be calculated } KvsRtcConfiguration, *PKvsRtcConfiguration; /** diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h index ce03a869a8..6ab13c43c6 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h @@ -72,7 +72,7 @@ extern "C" { /** * Maximum length of candidate type (host, srflx, relay, prflx, unknown) */ -#define MAX_CANDIDATE_TYPE_LENGTH 10U +#define MAX_CANDIDATE_TYPE_LENGTH 10U /*!@} */ /** @@ -243,14 +243,14 @@ typedef struct { * Reference: https://www.w3.org/TR/webrtc-stats/#ice-server-dict* */ typedef struct { - CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be - //!< populated by the application to get specific server stats - INT32 port; //!< Port number used by client - UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server - UINT64 totalResponsesReceived; //!< Total number of responses received from the server - UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be + //!< populated by the application to get specific server stats + INT32 port; //!< Port number used by client + UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server + UINT64 totalResponsesReceived; //!< Total number of responses received from the server + UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received } RtcIceServerStats, *PRtcIceServerStats; /** @@ -277,14 +277,14 @@ typedef struct { */ typedef struct { - DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) - //!< Valid values: UDP, TCP, TLS - INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 - INT32 port; //!< Port number of the candidate - CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate + DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained + CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) + //!< Valid values: UDP, TCP, TLS + INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 + INT32 port; //!< Port number of the candidate + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate } RtcIceCandidateStats, *PRtcIceCandidateStats; /** diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index c74be54e0d..01c8031861 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -81,7 +81,6 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge pIceAgent->pConnectionListener = pConnectionListener; pIceAgent->pDataSendingIceCandidatePair = NULL; pIceAgent->iceAgentState = ICE_AGENT_STATE_NEW; - pIceAgent->enableIceStats = pRtcConfiguration->kvsRtcConfiguration.enableIceStats; CHK_STATUS(createTransactionIdStore(DEFAULT_MAX_STORED_TRANSACTION_ID_COUNT, &pIceAgent->pStunBindingRequestTransactionIdStore)); pIceAgent->relayCandidateCount = 0; @@ -95,6 +94,7 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge // no other attribtues needed: https://tools.ietf.org/html/rfc8445#section-11 CHK_STATUS(createStunPacket(STUN_PACKET_TYPE_BINDING_INDICATION, NULL, &pIceAgent->pBindingIndication)); + CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceAgent->requestTimestampDiagnostics)); pIceAgent->iceServersCount = 0; for (i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { @@ -109,22 +109,18 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge (PCHAR) pRtcConfiguration->iceServers[i].username, (PCHAR) pRtcConfiguration->iceServers[i].credential), pIceAgent->iceAgentProfileDiagnostics.iceServerParsingTime[i], "ICE server parsing"); if (STATUS_SUCCEEDED(retStatus)) { - if (pIceAgent->enableIceStats) { - CHK(NULL != (pIceAgent->pRtcIceServerDiagnostics[i] = (PRtcIceServerDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceServerDiagnostics))), - STATUS_NOT_ENOUGH_MEMORY); - pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); - switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { - case KVS_SOCKET_PROTOCOL_UDP: - STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); - break; - case KVS_SOCKET_PROTOCOL_TCP: - STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_TCP); - break; - default: - MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); - } - STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pRtcConfiguration->iceServers[i].urls); + pIceAgent->rtcIceServerDiagnostics[i].port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { + case KVS_SOCKET_PROTOCOL_UDP: + STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_UDP); + break; + case KVS_SOCKET_PROTOCOL_TCP: + STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_TCP); + break; + default: + MEMSET(pIceAgent->rtcIceServerDiagnostics[i].protocol, 0, SIZEOF(pIceAgent->rtcIceServerDiagnostics[i].protocol)); } + STRCPY(pIceAgent->rtcIceServerDiagnostics[i].url, pRtcConfiguration->iceServers[i].urls); pIceAgent->iceServersCount++; } else { DLOGE("Failed to parse ICE servers"); @@ -132,17 +128,6 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge } } - if (pIceAgent->enableIceStats) { - CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceAgent->requestTimestampDiagnostics)); - CHK(NULL != - (pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics = - (PRtcIceCandidateDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidateDiagnostics))), - STATUS_NOT_ENOUGH_MEMORY); - CHK(NULL != - (pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics = - (PRtcIceCandidateDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidateDiagnostics))), - STATUS_NOT_ENOUGH_MEMORY); - } CleanUp: if (STATUS_FAILED(retStatus) && pIceAgent != NULL) { @@ -271,12 +256,6 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) freeTransactionIdStore(&pIceAgent->pStunBindingRequestTransactionIdStore); } - SAFE_MEMFREE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics); - SAFE_MEMFREE(pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics); - for (int i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { - SAFE_MEMFREE(pIceAgent->pRtcIceServerDiagnostics[i]); - } - MEMFREE(pIceAgent); *ppIceAgent = NULL; @@ -309,21 +288,18 @@ STATUS iceAgentAddConfig(PIceAgent pIceAgent, PIceConfigInfo pIceConfigInfo) if (STATUS_SUCCEEDED(retStatus)) { MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - if (pIceAgent->pRtcIceServerDiagnostics[i] != NULL) { - pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); - switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { - case KVS_SOCKET_PROTOCOL_UDP: - STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); - break; - case KVS_SOCKET_PROTOCOL_TCP: - STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_TCP); - break; - default: - MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); - } - - STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pIceConfigInfo->uris[i]); + pIceAgent->rtcIceServerDiagnostics[i].port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { + case KVS_SOCKET_PROTOCOL_UDP: + STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_UDP); + break; + case KVS_SOCKET_PROTOCOL_TCP: + STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_TCP); + break; + default: + MEMSET(pIceAgent->rtcIceServerDiagnostics[i].protocol, 0, SIZEOF(pIceAgent->rtcIceServerDiagnostics[i].protocol)); } + STRCPY(pIceAgent->rtcIceServerDiagnostics[i].url, pIceConfigInfo->uris[i]); MUTEX_UNLOCK(pIceAgent->lock); locked = FALSE; @@ -791,18 +767,17 @@ STATUS iceAgentSendPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen) packetsSent++; } + CleanUp: if (STATUS_SUCCEEDED(retStatus) && pIceAgent->pDataSendingIceCandidatePair != NULL) { - if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->packetsDiscardedOnSend += packetsDiscarded; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesDiscardedOnSend += bytesDiscarded; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->state = pIceAgent->pDataSendingIceCandidatePair->state; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp = - pIceAgent->pDataSendingIceCandidatePair->lastDataSentTime; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesSent += bytesSent; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->packetsSent += packetsSent; - } + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.packetsDiscardedOnSend += packetsDiscarded; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesDiscardedOnSend += bytesDiscarded; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.state = pIceAgent->pDataSendingIceCandidatePair->state; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketSentTimestamp = + pIceAgent->pDataSendingIceCandidatePair->lastDataSentTime; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesSent += bytesSent; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.packetsSent += packetsSent; } if (locked) { @@ -1174,12 +1149,6 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, // pair local and remote candidates with the same family if (pCurrentIceCandidate->state == ICE_CANDIDATE_STATE_VALID && pCurrentIceCandidate->ipAddress.family == pIceCandidate->ipAddress.family) { pIceCandidatePair = (PIceCandidatePair) MEMCALLOC(1, SIZEOF(IceCandidatePair)); - if (pIceAgent->enableIceStats) { - CHK(NULL != - (pIceCandidatePair->pRtcIceCandidatePairDiagnostics = - (PRtcIceCandidatePairDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidatePairDiagnostics))), - STATUS_NOT_ENOUGH_MEMORY); - } CHK(pIceCandidatePair != NULL, STATUS_NOT_ENOUGH_MEMORY); if (isRemoteCandidate) { @@ -1200,21 +1169,19 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceCandidatePair->requestSentTime)); pIceCandidatePair->lastDataSentTime = 0; - if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - STRNCPY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->localCandidateId, pIceCandidatePair->local->id, - ARRAY_SIZE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->localCandidateId)); - STRNCPY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->remoteCandidateId, pIceCandidatePair->remote->id, - ARRAY_SIZE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->remoteCandidateId)); - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->state = pIceCandidatePair->state; - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp = pIceCandidatePair->lastDataSentTime; - pIceCandidatePair->priority = computeCandidatePairPriority(pIceCandidatePair, pIceAgent->isControlling); - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->totalRoundTripTime = 0.0; - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->currentRoundTripTime = 0.0; - // Set data sending ICE candidate pair stats - NULLABLE_SET_EMPTY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->circuitBreakerTriggerCount); - } + STRNCPY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.localCandidateId, pIceCandidatePair->local->id, + ARRAY_SIZE(pIceCandidatePair->rtcIceCandidatePairDiagnostics.localCandidateId)); + STRNCPY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.remoteCandidateId, pIceCandidatePair->remote->id, + ARRAY_SIZE(pIceCandidatePair->rtcIceCandidatePairDiagnostics.remoteCandidateId)); + pIceCandidatePair->rtcIceCandidatePairDiagnostics.state = pIceCandidatePair->state; + pIceCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; + pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketSentTimestamp = pIceCandidatePair->lastDataSentTime; pIceCandidatePair->firstStunRequest = TRUE; + pIceCandidatePair->priority = computeCandidatePairPriority(pIceCandidatePair, pIceAgent->isControlling); + pIceCandidatePair->rtcIceCandidatePairDiagnostics.totalRoundTripTime = 0.0; + pIceCandidatePair->rtcIceCandidatePairDiagnostics.currentRoundTripTime = 0.0; + // Set data sending ICE candidate pair stats + NULLABLE_SET_EMPTY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.circuitBreakerTriggerCount); CHK_STATUS(insertIceCandidatePair(pIceAgent->iceCandidatePairs, pIceCandidatePair)); freeObjOnFailure = FALSE; } @@ -1243,7 +1210,6 @@ STATUS freeIceCandidatePair(PIceCandidatePair* ppIceCandidatePair) CHK(*ppIceCandidatePair != NULL, retStatus); pIceCandidatePair = *ppIceCandidatePair; - SAFE_MEMFREE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics); CHK_LOG_ERR(freeTransactionIdStore(&pIceCandidatePair->pTransactionIdStore)); CHK_LOG_ERR(hashTableFree(pIceCandidatePair->requestSentTime)); SAFE_MEMFREE(pIceCandidatePair); @@ -1387,23 +1353,18 @@ STATUS iceCandidatePairCheckConnection(PStunPacket pStunBindingRequest, PIceAgen transactionIdStoreInsert(pIceCandidatePair->pTransactionIdStore, pStunBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pStunBindingRequest->header.transactionId, ARRAY_SIZE(pStunBindingRequest->header.transactionId)); CHK_STATUS(hashTableUpsert(pIceCandidatePair->requestSentTime, checkSum, GETTIME())); - if (pIceAgent->requestTimestampDiagnostics != NULL) { - CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); - } + CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); - if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && - pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex] != NULL) { - pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalRequestsSent++; + if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { + pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRequestsSent++; } CHK_STATUS(iceAgentSendStunPacket(pStunBindingRequest, (PBYTE) pIceAgent->remotePassword, (UINT32) STRLEN(pIceAgent->remotePassword) * SIZEOF(CHAR), pIceAgent, pIceCandidatePair->local, &pIceCandidatePair->remote->ipAddress)); - if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastRequestTimestamp = GETTIME(); - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->requestsSent++; - } + pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastRequestTimestamp = GETTIME(); + pIceCandidatePair->rtcIceCandidatePairDiagnostics.requestsSent++; CleanUp: CHK_LOG_ERR(retStatus); @@ -1448,9 +1409,7 @@ STATUS iceAgentSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa &pIceCandidatePair)); if (pIceCandidatePair != NULL && pIceCandidatePair == pIceAgent->pDataSendingIceCandidatePair && pIceAgent->pDataSendingIceCandidatePair->firstStunRequest) { - if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->firstRequestTimestamp = GETTIME(); - } + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.firstRequestTimestamp = GETTIME(); pIceAgent->pDataSendingIceCandidatePair->firstStunRequest = FALSE; } } @@ -1530,10 +1489,8 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddress)); - if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { - pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex]->totalRequestsSent++; - CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); - } + pIceAgent->rtcIceServerDiagnostics[pCandidate->iceServerIndex].totalRequestsSent++; + CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); } break; @@ -2084,12 +2041,10 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) STATUS retStatus = STATUS_SUCCESS; CHK(pIceAgent != NULL && pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_NULL_ARG); PIceCandidate pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->remote; - - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; - CHK(pRtcIceCandidateDiagnostics != NULL, STATUS_SUCCESS); + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedRemoteIceCandidateDiagnostics; if (!isRemote) { pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->local; - pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; + pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedLocalIceCandidateDiagnostics; STRNCPY(pRtcIceCandidateDiagnostics->url, STATS_NOT_APPLICABLE_STR, ARRAY_SIZE(pRtcIceCandidateDiagnostics->url)); // URL and relay protocol are populated only for local candidate by spec. // If candidate type is host, there is no URL and is set to N/A @@ -2108,7 +2063,7 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) break; case KVS_SOCKET_PROTOCOL_TCP: STRNCPY(pRtcIceCandidateDiagnostics->relayProtocol, ICE_TRANSPORT_TYPE_TCP, - ARRAY_SIZE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics->relayProtocol)); + ARRAY_SIZE(pIceAgent->rtcSelectedLocalIceCandidateDiagnostics.relayProtocol)); break; default: MEMSET(pRtcIceCandidateDiagnostics->relayProtocol, 0, SIZEOF(pRtcIceCandidateDiagnostics->relayProtocol)); @@ -2122,8 +2077,8 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) ARRAY_SIZE(pRtcIceCandidateDiagnostics->candidateType)); STRNCPY(pRtcIceCandidateDiagnostics->protocol, ICE_TRANSPORT_TYPE_UDP, ARRAY_SIZE(pRtcIceCandidateDiagnostics->protocol)); - if (pIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex] != NULL) { - STRNCPY(pRtcIceCandidateDiagnostics->protocol, pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->protocol, + if (pIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { + STRNCPY(pRtcIceCandidateDiagnostics->protocol, pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].protocol, ARRAY_SIZE(pRtcIceCandidateDiagnostics->protocol)); } CleanUp: @@ -2286,9 +2241,7 @@ STATUS iceAgentReadyStateSetup(PIceAgent pIceAgent) pCurNode = pCurNode->pNext; if (pIceCandidatePair->nominated && pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { pNominatedAndValidCandidatePair = pIceCandidatePair; - if (pNominatedAndValidCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pNominatedAndValidCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; - } + pNominatedAndValidCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; break; } } @@ -2494,12 +2447,10 @@ STATUS incomingDataHandler(UINT64 customData, PSocketConnection pSocketConnectio pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.family == pSrc->family && MEMCMP(pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.address, pSrc->address, addrLen) == 0 && (pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.port == pSrc->port)) { - if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketReceivedTimestamp = GETTIME(); - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesReceived += bufferLen; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics - ->packetsReceived++; // Since every byte buffer translates to a single RTP packet - } + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketReceivedTimestamp = GETTIME(); + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesReceived += bufferLen; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics + .packetsReceived++; // Since every byte buffer translates to a single RTP packet } } else { if (ATOMIC_LOAD_BOOL(&pIceAgent->processStun)) { @@ -2630,11 +2581,9 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } if (pIceCandidatePair == pIceAgent->pDataSendingIceCandidatePair) { - if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->requestsReceived += connectivityCheckRequestsReceived; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->responsesSent += connectivityCheckResponsesSent; - pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; - } + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.requestsReceived += connectivityCheckRequestsReceived; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.responsesSent += connectivityCheckResponsesSent; + pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; } else { DLOGD("going to change the data sending ice candidate pair."); } @@ -2650,15 +2599,13 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pSocketConnection->localSocket); // Update round trip time for serial reflexive candidate - if (pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex] != NULL) { - pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->totalResponsesReceived++; - // Transaction ID count be same for candidates coming from same interface, which means there would only - // be one entry. It is not necessary to update a return sttaus since it is not indicative of a failure - if ((hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime)) == STATUS_SUCCESS) { - pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->totalRoundTripTime += GETTIME() - requestSentTime; - CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); - hashTableGetCount(pIceAgent->requestTimestampDiagnostics, &count); - } + pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalResponsesReceived++; + // Transaction ID count be same for candidates coming from same interface, which means there would only + // be one entry. It is not necessary to update a return sttaus since it is not indicative of a failure + if ((hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime)) == STATUS_SUCCESS) { + pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; + CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); + hashTableGetCount(pIceAgent->requestTimestampDiagnostics, &count); } CHK_STATUS(deserializeStunPacket(pBuffer, bufferLen, NULL, 0, &pStunPacket)); @@ -2684,28 +2631,22 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS ipAddrStr2, ipAddrStr); } DLOGD("Pair binding response! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); - if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { - pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; - if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->currentRoundTripTime = - (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; - } - } else { - DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); - } + if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { + pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; + pIceCandidatePair->rtcIceCandidatePairDiagnostics.currentRoundTripTime = + (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + } else { + DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); } - CHK_WARN(transactionIdStoreHasId(pIceCandidatePair->pTransactionIdStore, pBuffer + STUN_PACKET_TRANSACTION_ID_OFFSET), retStatus, "Dropping response packet because transaction id does not match"); // Update round trip time and responses received only for relay candidates. - if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && - pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex] != NULL) { - pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalResponsesReceived++; + if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { + pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalResponsesReceived++; retStatus = hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime); if (hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime) == STATUS_SUCCESS) { - pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalRoundTripTime += GETTIME() - requestSentTime; + pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); } } @@ -2738,10 +2679,8 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; DLOGD("Ice candidate pair %s_%s is connected. Round trip time: %" PRIu64 "ms", pIceCandidatePair->local->id, pIceCandidatePair->remote->id, pIceCandidatePair->roundTripTime / HUNDREDS_OF_NANOS_IN_A_MILLISECOND); - if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->totalRoundTripTime += - (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; - } + pIceCandidatePair->rtcIceCandidatePairDiagnostics.totalRoundTripTime += + (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; CHK_STATUS(hashTableRemove(pIceCandidatePair->requestSentTime, checkSum)); } else { @@ -2749,10 +2688,8 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } } - if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->responsesReceived += connectivityCheckResponsesReceived; - pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastResponseTimestamp = GETTIME(); - } + pIceCandidatePair->rtcIceCandidatePairDiagnostics.responsesReceived += connectivityCheckResponsesReceived; + pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastResponseTimestamp = GETTIME(); break; case STUN_PACKET_TYPE_BINDING_INDICATION: diff --git a/src/source/Ice/IceAgent.h b/src/source/Ice/IceAgent.h index 778ba6e9b7..0f82748485 100644 --- a/src/source/Ice/IceAgent.h +++ b/src/source/Ice/IceAgent.h @@ -80,23 +80,23 @@ typedef struct __IceAgent* PIceAgent; * Internal structure tracking ICE server parameters for diagnostics and metrics/stats */ typedef struct { - CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - INT32 port; //!< Port number used by client - UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server - UINT64 totalResponsesReceived; //!< Total number of responses received from the server - UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + INT32 port; //!< Port number used by client + UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server + UINT64 totalResponsesReceived; //!< Total number of responses received from the server + UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received } RtcIceServerDiagnostics, *PRtcIceServerDiagnostics; typedef struct { - DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. - //!< Valid values: UDP, TCP, TLS - CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate - INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 - INT32 port; //!< Port number of the candidate + DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained + CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. + //!< Valid values: UDP, TCP, TLS + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate + INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 + INT32 port; //!< Port number of the candidate } RtcIceCandidateDiagnostics, *PRtcIceCandidateDiagnostics; typedef struct { @@ -182,7 +182,7 @@ typedef struct { PHashTable requestSentTime; UINT64 roundTripTime; UINT64 responsesReceived; - PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics; + RtcIceCandidatePairDiagnostics rtcIceCandidatePairDiagnostics; } IceCandidatePair, *PIceCandidatePair; typedef struct { @@ -210,9 +210,9 @@ struct __IceAgent { CHAR remotePassword[MAX_ICE_CONFIG_CREDENTIAL_LEN + 1]; CHAR combinedUserName[(MAX_ICE_CONFIG_USER_NAME_LEN + 1) << 1]; //!< the combination of remote user name and local user name. - PRtcIceServerDiagnostics pRtcIceServerDiagnostics[MAX_ICE_SERVERS_COUNT]; - PRtcIceCandidateDiagnostics pRtcSelectedLocalIceCandidateDiagnostics; - PRtcIceCandidateDiagnostics pRtcSelectedRemoteIceCandidateDiagnostics; + RtcIceServerDiagnostics rtcIceServerDiagnostics[MAX_ICE_SERVERS_COUNT]; + RtcIceCandidateDiagnostics rtcSelectedLocalIceCandidateDiagnostics; + RtcIceCandidateDiagnostics rtcSelectedRemoteIceCandidateDiagnostics; IceAgentProfileDiagnostics iceAgentProfileDiagnostics; PHashTable requestTimestampDiagnostics; @@ -273,7 +273,6 @@ struct __IceAgent { UINT64 candidateGatheringStartTime; UINT64 candidateGatheringProcessEndTime; UINT64 iceAgentStartTime; - BOOL enableIceStats; }; ////////////////////////////////////////////// diff --git a/src/source/Metrics/Metrics.c b/src/source/Metrics/Metrics.c index bddcc74d8b..f39c3e0292 100644 --- a/src/source/Metrics/Metrics.c +++ b/src/source/Metrics/Metrics.c @@ -14,8 +14,7 @@ STATUS getIceCandidatePairStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceCa MUTEX_LOCK(pIceAgent->lock); locked = TRUE; CHK(pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_SUCCESS); - PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics; - CHK_WARN(pRtcIceCandidatePairDiagnostics != NULL, STATUS_NULL_ARG, "Candidate pair not populated"); + PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = &pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics; STRCPY(pRtcIceCandidatePairStats->localCandidateId, pRtcIceCandidatePairDiagnostics->localCandidateId); STRCPY(pRtcIceCandidatePairStats->remoteCandidateId, pRtcIceCandidatePairDiagnostics->remoteCandidateId); pRtcIceCandidatePairStats->state = pRtcIceCandidatePairDiagnostics->state; @@ -60,10 +59,9 @@ STATUS getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote CHK((pRtcPeerConnection != NULL || pRtcIceCandidateStats != NULL), STATUS_NULL_ARG); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; - CHK_WARN(pRtcIceCandidateDiagnostics != NULL, STATUS_NULL_ARG, "Candidate stats not populated"); + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedRemoteIceCandidateDiagnostics; if (!isRemote) { - pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; + pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedLocalIceCandidateDiagnostics; STRCPY(pRtcIceCandidateStats->relayProtocol, pRtcIceCandidateDiagnostics->relayProtocol); STRCPY(pRtcIceCandidateStats->url, pRtcIceCandidateDiagnostics->url); } @@ -89,12 +87,12 @@ STATUS getIceServerStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceServerSta MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - pRtcIceServerStats->port = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->port; - STRCPY(pRtcIceServerStats->protocol, pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->protocol); - STRCPY(pRtcIceServerStats->url, pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->url); - pRtcIceServerStats->totalRequestsSent = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalRequestsSent; - pRtcIceServerStats->totalResponsesReceived = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalResponsesReceived; - pRtcIceServerStats->totalRoundTripTime = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalRoundTripTime; + pRtcIceServerStats->port = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].port; + STRCPY(pRtcIceServerStats->protocol, pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].protocol); + STRCPY(pRtcIceServerStats->url, pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].url); + pRtcIceServerStats->totalRequestsSent = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalRequestsSent; + pRtcIceServerStats->totalResponsesReceived = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalResponsesReceived; + pRtcIceServerStats->totalRoundTripTime = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalRoundTripTime; CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index f02d55e897..4ea9f8153c 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -341,9 +341,11 @@ STATUS changePeerConnectionState(PKvsPeerConnection pKvsPeerConnection, RTC_PEER customData = pKvsPeerConnection->onConnectionStateChangeCustomData; MUTEX_UNLOCK(pKvsPeerConnection->peerConnectionObjLock); locked = FALSE; + if (onConnectionStateChange != NULL) { onConnectionStateChange(customData, newState); } + CleanUp: if (locked) { diff --git a/tst/MetricsApiTest.cpp b/tst/MetricsApiTest.cpp index 2141ebaf8a..7484d2db94 100644 --- a/tst/MetricsApiTest.cpp +++ b/tst/MetricsApiTest.cpp @@ -56,7 +56,6 @@ TEST_F(MetricsApiTest, webRtcIceServerGetMetrics) STRNCPY(configuration.iceServers[1].urls, (PCHAR) "turns:54.202.170.151:443?transport=tcp", MAX_ICE_CONFIG_URI_LEN); STRNCPY(configuration.iceServers[1].credential, (PCHAR) "username", MAX_ICE_CONFIG_CREDENTIAL_LEN); STRNCPY(configuration.iceServers[1].username, (PCHAR) "password", MAX_ICE_CONFIG_USER_NAME_LEN); - configuration.kvsRtcConfiguration.enableIceStats = TRUE; ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); @@ -90,7 +89,7 @@ TEST_F(MetricsApiTest, webRtcIceCandidateGetMetrics) STRNCPY(configuration.iceServers[0].urls, (PCHAR) "stun:stun.kinesisvideo.us-west-2.amazonaws.com:443", MAX_ICE_CONFIG_URI_LEN); STRNCPY(configuration.iceServers[0].credential, (PCHAR) "", MAX_ICE_CONFIG_CREDENTIAL_LEN); STRNCPY(configuration.iceServers[0].username, (PCHAR) "", MAX_ICE_CONFIG_USER_NAME_LEN); - configuration.kvsRtcConfiguration.enableIceStats = TRUE; + ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); pIceAgent = ((PKvsPeerConnection) pRtcPeerConnection)->pIceAgent; From dcd62b7e371e42dca6d9353ff09e24b64d1eb525 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Fri, 8 Mar 2024 14:30:41 -0800 Subject: [PATCH 06/11] Working version --- samples/Common.c | 31 ++- .../kinesis/video/webrtcclient/Include.h | 1 + .../kinesis/video/webrtcclient/Stats.h | 34 +-- src/source/Ice/IceAgent.c | 232 +++++++++++------- src/source/Ice/IceAgent.h | 36 +-- src/source/Metrics/Metrics.c | 92 +++---- 6 files changed, 244 insertions(+), 182 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index 33ee18b1e5..a09a70e562 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -114,21 +114,21 @@ STATUS logSelectedIceCandidatesInformation(PSampleStreamingSession pSampleStream CHK(pSampleStreamingSession != NULL, STATUS_NULL_ARG); rtcMetrics.requestedTypeOfStats = RTC_STATS_TYPE_LOCAL_CANDIDATE; CHK_STATUS(rtcPeerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, NULL, &rtcMetrics)); - DLOGD("Local Candidate IP Address: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.address); - DLOGD("Local Candidate type: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.candidateType); - DLOGD("Local Candidate port: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.port); - DLOGD("Local Candidate priority: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.priority); - DLOGD("Local Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.protocol); - DLOGD("Local Candidate relay protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.relayProtocol); - DLOGD("Local Candidate Ice server source: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.url); + DLOGI("Local Candidate IP Address: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.address); + DLOGI("Local Candidate type: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.candidateType); + DLOGI("Local Candidate port: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.port); + DLOGI("Local Candidate priority: %d", rtcMetrics.rtcStatsObject.localIceCandidateStats.priority); + DLOGI("Local Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.protocol); + DLOGI("Local Candidate relay protocol: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.relayProtocol); + DLOGI("Local Candidate Ice server source: %s", rtcMetrics.rtcStatsObject.localIceCandidateStats.url); rtcMetrics.requestedTypeOfStats = RTC_STATS_TYPE_REMOTE_CANDIDATE; CHK_STATUS(rtcPeerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, NULL, &rtcMetrics)); - DLOGD("Remote Candidate IP Address: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.address); - DLOGD("Remote Candidate type: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.candidateType); - DLOGD("Remote Candidate port: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.port); - DLOGD("Remote Candidate priority: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.priority); - DLOGD("Remote Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.protocol); + DLOGI("Remote Candidate IP Address: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.address); + DLOGI("Remote Candidate type: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.candidateType); + DLOGI("Remote Candidate port: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.port); + DLOGI("Remote Candidate priority: %d", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.priority); + DLOGI("Remote Candidate transport protocol: %s", rtcMetrics.rtcStatsObject.remoteIceCandidateStats.protocol); CleanUp: LEAVES(); return retStatus; @@ -398,6 +398,8 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP // Set the ICE mode explicitly configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL; + configuration.kvsRtcConfiguration.enableIceStats = TRUE; + // Set the STUN server PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; // If region is in CN, add CN region uri postfix @@ -1202,10 +1204,7 @@ STATUS freeSampleConfiguration(PSampleConfiguration* ppSampleConfiguration) } for (i = 0; i < pSampleConfiguration->streamingSessionCount; ++i) { - retStatus = gatherIceServerStats(pSampleConfiguration->sampleStreamingSessionList[i]); - if (STATUS_FAILED(retStatus)) { - DLOGW("Failed to ICE Server Stats for streaming session %d: %08x", i, retStatus); - } + CHK_LOG_ERR(gatherIceServerStats(pSampleConfiguration->sampleStreamingSessionList[i])); freeSampleStreamingSession(&pSampleConfiguration->sampleStreamingSessionList[i]); } if (locked) { diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h index 59569fb591..0676c5d095 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h @@ -1215,6 +1215,7 @@ typedef struct { BOOL disableSenderSideBandwidthEstimation; //!< Disable TWCC feedback based sender bandwidth estimation, enabled by default. //!< You want to set this to TRUE if you are on a very stable connection and want to save 1.2MB of //!< memory + BOOL enableIceStats; //!< Enable ICE stats to be calculated } KvsRtcConfiguration, *PKvsRtcConfiguration; /** diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h index 6ab13c43c6..ce03a869a8 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Stats.h @@ -72,7 +72,7 @@ extern "C" { /** * Maximum length of candidate type (host, srflx, relay, prflx, unknown) */ -#define MAX_CANDIDATE_TYPE_LENGTH 10U +#define MAX_CANDIDATE_TYPE_LENGTH 10U /*!@} */ /** @@ -243,14 +243,14 @@ typedef struct { * Reference: https://www.w3.org/TR/webrtc-stats/#ice-server-dict* */ typedef struct { - CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be - //!< populated by the application to get specific server stats - INT32 port; //!< Port number used by client - UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server - UINT64 totalResponsesReceived; //!< Total number of responses received from the server - UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + UINT32 iceServerIndex; //!< Ice server index to get stats from. Not available in spec! Needs to be + //!< populated by the application to get specific server stats + INT32 port; //!< Port number used by client + UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server + UINT64 totalResponsesReceived; //!< Total number of responses received from the server + UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received } RtcIceServerStats, *PRtcIceServerStats; /** @@ -277,14 +277,14 @@ typedef struct { */ typedef struct { - DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) - //!< Valid values: UDP, TCP, TLS - INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 - INT32 port; //!< Port number of the candidate - CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate + DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained + CHAR address[IP_ADDR_STR_LENGTH + 1]; //!< IPv4 or IPv6 address of the candidate + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. (Only for local candidate) + //!< Valid values: UDP, TCP, TLS + INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 + INT32 port; //!< Port number of the candidate + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate } RtcIceCandidateStats, *PRtcIceCandidateStats; /** diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 01c8031861..4a743a1f71 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -109,25 +109,39 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge (PCHAR) pRtcConfiguration->iceServers[i].username, (PCHAR) pRtcConfiguration->iceServers[i].credential), pIceAgent->iceAgentProfileDiagnostics.iceServerParsingTime[i], "ICE server parsing"); if (STATUS_SUCCEEDED(retStatus)) { - pIceAgent->rtcIceServerDiagnostics[i].port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); - switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { - case KVS_SOCKET_PROTOCOL_UDP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_UDP); - break; - case KVS_SOCKET_PROTOCOL_TCP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_TCP); - break; - default: - MEMSET(pIceAgent->rtcIceServerDiagnostics[i].protocol, 0, SIZEOF(pIceAgent->rtcIceServerDiagnostics[i].protocol)); + if (pIceAgent->kvsRtcConfiguration.enableIceStats) { + CHK(NULL != (pIceAgent->pRtcIceServerDiagnostics[i] = (PRtcIceServerDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceServerDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { + case KVS_SOCKET_PROTOCOL_UDP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); + break; + case KVS_SOCKET_PROTOCOL_TCP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_TCP); + break; + default: + MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); + } + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pRtcConfiguration->iceServers[i].urls); + pIceAgent->iceServersCount++; } - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].url, pRtcConfiguration->iceServers[i].urls); - pIceAgent->iceServersCount++; } else { DLOGE("Failed to parse ICE servers"); } } } + if (pIceAgent->kvsRtcConfiguration.enableIceStats) { + CHK(NULL != + (pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics = + (PRtcIceCandidateDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidateDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + CHK(NULL != + (pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics = + (PRtcIceCandidateDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidateDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); + } CleanUp: if (STATUS_FAILED(retStatus) && pIceAgent != NULL) { @@ -165,8 +179,6 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) pIceAgent = *ppIceAgent; - hashTableFree(pIceAgent->requestTimestampDiagnostics); - if (pIceAgent->localCandidates != NULL) { CHK_STATUS(doubleListGetHeadNode(pIceAgent->localCandidates, &pCurNode)); while (pCurNode != NULL) { @@ -256,6 +268,12 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) freeTransactionIdStore(&pIceAgent->pStunBindingRequestTransactionIdStore); } + hashTableFree(pIceAgent->requestTimestampDiagnostics); + SAFE_MEMFREE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics); + SAFE_MEMFREE(pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics); + for (int i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { + SAFE_MEMFREE(pIceAgent->pRtcIceServerDiagnostics[i]); + } MEMFREE(pIceAgent); *ppIceAgent = NULL; @@ -288,19 +306,20 @@ STATUS iceAgentAddConfig(PIceAgent pIceAgent, PIceConfigInfo pIceConfigInfo) if (STATUS_SUCCEEDED(retStatus)) { MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - pIceAgent->rtcIceServerDiagnostics[i].port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); - switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { - case KVS_SOCKET_PROTOCOL_UDP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_UDP); - break; - case KVS_SOCKET_PROTOCOL_TCP: - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].protocol, ICE_TRANSPORT_TYPE_TCP); - break; - default: - MEMSET(pIceAgent->rtcIceServerDiagnostics[i].protocol, 0, SIZEOF(pIceAgent->rtcIceServerDiagnostics[i].protocol)); + if (pIceAgent->pRtcIceServerDiagnostics[i] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[i]->port = (INT32) getInt16(pIceAgent->iceServers[i].ipAddress.port); + switch (pIceAgent->iceServers[pIceAgent->iceServersCount].transport) { + case KVS_SOCKET_PROTOCOL_UDP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_UDP); + break; + case KVS_SOCKET_PROTOCOL_TCP: + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, ICE_TRANSPORT_TYPE_TCP); + break; + default: + MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); + } + STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pIceConfigInfo->uris[i]); } - STRCPY(pIceAgent->rtcIceServerDiagnostics[i].url, pIceConfigInfo->uris[i]); - MUTEX_UNLOCK(pIceAgent->lock); locked = FALSE; @@ -767,17 +786,18 @@ STATUS iceAgentSendPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen) packetsSent++; } - CleanUp: if (STATUS_SUCCEEDED(retStatus) && pIceAgent->pDataSendingIceCandidatePair != NULL) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.packetsDiscardedOnSend += packetsDiscarded; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesDiscardedOnSend += bytesDiscarded; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.state = pIceAgent->pDataSendingIceCandidatePair->state; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketSentTimestamp = - pIceAgent->pDataSendingIceCandidatePair->lastDataSentTime; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesSent += bytesSent; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.packetsSent += packetsSent; + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->packetsDiscardedOnSend += packetsDiscarded; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesDiscardedOnSend += bytesDiscarded; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->state = pIceAgent->pDataSendingIceCandidatePair->state; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp = + pIceAgent->pDataSendingIceCandidatePair->lastDataSentTime; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesSent += bytesSent; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->packetsSent += packetsSent; + } } if (locked) { @@ -1150,6 +1170,10 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, if (pCurrentIceCandidate->state == ICE_CANDIDATE_STATE_VALID && pCurrentIceCandidate->ipAddress.family == pIceCandidate->ipAddress.family) { pIceCandidatePair = (PIceCandidatePair) MEMCALLOC(1, SIZEOF(IceCandidatePair)); CHK(pIceCandidatePair != NULL, STATUS_NOT_ENOUGH_MEMORY); + if (pIceAgent->kvsRtcConfiguration.enableIceStats) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics = + (PRtcIceCandidatePairDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidatePairDiagnostics)); + } if (isRemoteCandidate) { // Since we pick local candidate list @@ -1169,19 +1193,23 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceCandidatePair->requestSentTime)); pIceCandidatePair->lastDataSentTime = 0; - STRNCPY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.localCandidateId, pIceCandidatePair->local->id, - ARRAY_SIZE(pIceCandidatePair->rtcIceCandidatePairDiagnostics.localCandidateId)); - STRNCPY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.remoteCandidateId, pIceCandidatePair->remote->id, - ARRAY_SIZE(pIceCandidatePair->rtcIceCandidatePairDiagnostics.remoteCandidateId)); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.state = pIceCandidatePair->state; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketSentTimestamp = pIceCandidatePair->lastDataSentTime; pIceCandidatePair->firstStunRequest = TRUE; pIceCandidatePair->priority = computeCandidatePairPriority(pIceCandidatePair, pIceAgent->isControlling); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.totalRoundTripTime = 0.0; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.currentRoundTripTime = 0.0; - // Set data sending ICE candidate pair stats - NULLABLE_SET_EMPTY(pIceCandidatePair->rtcIceCandidatePairDiagnostics.circuitBreakerTriggerCount); + + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + STRNCPY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->localCandidateId, pIceCandidatePair->local->id, + ARRAY_SIZE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->localCandidateId)); + STRNCPY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->remoteCandidateId, pIceCandidatePair->remote->id, + ARRAY_SIZE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->remoteCandidateId)); + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->state = pIceCandidatePair->state; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp = pIceCandidatePair->lastDataSentTime; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->totalRoundTripTime = 0.0; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->currentRoundTripTime = 0.0; + // Set data sending ICE candidate pair stats + NULLABLE_SET_EMPTY(pIceCandidatePair->pRtcIceCandidatePairDiagnostics->circuitBreakerTriggerCount); + } + CHK_STATUS(insertIceCandidatePair(pIceAgent->iceCandidatePairs, pIceCandidatePair)); freeObjOnFailure = FALSE; } @@ -1212,6 +1240,7 @@ STATUS freeIceCandidatePair(PIceCandidatePair* ppIceCandidatePair) CHK_LOG_ERR(freeTransactionIdStore(&pIceCandidatePair->pTransactionIdStore)); CHK_LOG_ERR(hashTableFree(pIceCandidatePair->requestSentTime)); + SAFE_MEMFREE(pIceCandidatePair->pRtcIceCandidatePairDiagnostics); SAFE_MEMFREE(pIceCandidatePair); CleanUp: @@ -1355,16 +1384,19 @@ STATUS iceCandidatePairCheckConnection(PStunPacket pStunBindingRequest, PIceAgen CHK_STATUS(hashTableUpsert(pIceCandidatePair->requestSentTime, checkSum, GETTIME())); CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); - if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRequestsSent++; + if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalRequestsSent++; } CHK_STATUS(iceAgentSendStunPacket(pStunBindingRequest, (PBYTE) pIceAgent->remotePassword, (UINT32) STRLEN(pIceAgent->remotePassword) * SIZEOF(CHAR), pIceAgent, pIceCandidatePair->local, &pIceCandidatePair->remote->ipAddress)); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastRequestTimestamp = GETTIME(); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.requestsSent++; + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastRequestTimestamp = GETTIME(); + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->requestsSent++; + } CleanUp: CHK_LOG_ERR(retStatus); @@ -1409,7 +1441,9 @@ STATUS iceAgentSendStunPacket(PStunPacket pStunPacket, PBYTE password, UINT32 pa &pIceCandidatePair)); if (pIceCandidatePair != NULL && pIceCandidatePair == pIceAgent->pDataSendingIceCandidatePair && pIceAgent->pDataSendingIceCandidatePair->firstStunRequest) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.firstRequestTimestamp = GETTIME(); + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->firstRequestTimestamp = GETTIME(); + } pIceAgent->pDataSendingIceCandidatePair->firstStunRequest = FALSE; } } @@ -1489,8 +1523,10 @@ STATUS iceAgentSendSrflxCandidateRequest(PIceAgent pIceAgent) transactionIdStoreInsert(pIceAgent->pStunBindingRequestTransactionIdStore, pBindingRequest->header.transactionId); checkSum = COMPUTE_CRC32(pBindingRequest->header.transactionId, ARRAY_SIZE(pBindingRequest->header.transactionId)); CHK_STATUS(iceAgentSendStunPacket(pBindingRequest, NULL, 0, pIceAgent, pCandidate, &pIceServer->ipAddress)); - pIceAgent->rtcIceServerDiagnostics[pCandidate->iceServerIndex].totalRequestsSent++; - CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + if (pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pCandidate->iceServerIndex]->totalRequestsSent++; + CHK_STATUS(hashTableUpsert(pIceAgent->requestTimestampDiagnostics, checkSum, GETTIME())); + } } break; @@ -2041,10 +2077,11 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) STATUS retStatus = STATUS_SUCCESS; CHK(pIceAgent != NULL && pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_NULL_ARG); PIceCandidate pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->remote; - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedRemoteIceCandidateDiagnostics; + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; if (!isRemote) { pIceCandidate = pIceAgent->pDataSendingIceCandidatePair->local; - pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedLocalIceCandidateDiagnostics; + pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; + CHK(pRtcIceCandidateDiagnostics != NULL, STATUS_SUCCESS); STRNCPY(pRtcIceCandidateDiagnostics->url, STATS_NOT_APPLICABLE_STR, ARRAY_SIZE(pRtcIceCandidateDiagnostics->url)); // URL and relay protocol are populated only for local candidate by spec. // If candidate type is host, there is no URL and is set to N/A @@ -2063,13 +2100,14 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) break; case KVS_SOCKET_PROTOCOL_TCP: STRNCPY(pRtcIceCandidateDiagnostics->relayProtocol, ICE_TRANSPORT_TYPE_TCP, - ARRAY_SIZE(pIceAgent->rtcSelectedLocalIceCandidateDiagnostics.relayProtocol)); + ARRAY_SIZE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics->relayProtocol)); break; default: MEMSET(pRtcIceCandidateDiagnostics->relayProtocol, 0, SIZEOF(pRtcIceCandidateDiagnostics->relayProtocol)); } } } + CHK(pRtcIceCandidateDiagnostics != NULL, STATUS_SUCCESS); getIpAddrStr(&pIceCandidate->ipAddress, pRtcIceCandidateDiagnostics->address, ARRAY_SIZE(pRtcIceCandidateDiagnostics->address)); pRtcIceCandidateDiagnostics->port = (UINT16) getInt16(pIceCandidate->ipAddress.port); pRtcIceCandidateDiagnostics->priority = pIceCandidate->priority; @@ -2077,8 +2115,8 @@ STATUS updateCandidateStats(PIceAgent pIceAgent, BOOL isRemote) ARRAY_SIZE(pRtcIceCandidateDiagnostics->candidateType)); STRNCPY(pRtcIceCandidateDiagnostics->protocol, ICE_TRANSPORT_TYPE_UDP, ARRAY_SIZE(pRtcIceCandidateDiagnostics->protocol)); - if (pIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { - STRNCPY(pRtcIceCandidateDiagnostics->protocol, pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].protocol, + if (pIceCandidate->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED && pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex] != NULL) { + STRNCPY(pRtcIceCandidateDiagnostics->protocol, pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->protocol, ARRAY_SIZE(pRtcIceCandidateDiagnostics->protocol)); } CleanUp: @@ -2143,10 +2181,6 @@ STATUS iceAgentConnectedStateSetup(PIceAgent pIceAgent) if (pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED && pIceCandidatePair->nominated) { pIceAgent->pDataSendingIceCandidatePair = pIceCandidatePair; - retStatus = updateSelectedLocalRemoteCandidateStats(pIceAgent); - if (STATUS_FAILED(retStatus)) { - DLOGW("Failed to update candidate stats with status code 0x%08x", retStatus); - } break; } } @@ -2241,7 +2275,9 @@ STATUS iceAgentReadyStateSetup(PIceAgent pIceAgent) pCurNode = pCurNode->pNext; if (pIceCandidatePair->nominated && pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { pNominatedAndValidCandidatePair = pIceCandidatePair; - pNominatedAndValidCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; + if (pNominatedAndValidCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pNominatedAndValidCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; + } break; } } @@ -2258,6 +2294,8 @@ STATUS iceAgentReadyStateSetup(PIceAgent pIceAgent) pIceAgent->pDataSendingIceCandidatePair->roundTripTime / HUNDREDS_OF_NANOS_IN_A_MILLISECOND, pIceAgent->pDataSendingIceCandidatePair->local->priority, pIceAgent->pDataSendingIceCandidatePair->priority); + CHK_LOG_ERR(updateSelectedLocalRemoteCandidateStats(pIceAgent)); + /* no state timeout for ready state */ pIceAgent->stateEndTime = INVALID_TIMESTAMP_VALUE; @@ -2447,10 +2485,12 @@ STATUS incomingDataHandler(UINT64 customData, PSocketConnection pSocketConnectio pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.family == pSrc->family && MEMCMP(pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.address, pSrc->address, addrLen) == 0 && (pIceAgent->pDataSendingIceCandidatePair->remote->ipAddress.port == pSrc->port)) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.lastPacketReceivedTimestamp = GETTIME(); - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.bytesReceived += bufferLen; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics - .packetsReceived++; // Since every byte buffer translates to a single RTP packet + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastPacketReceivedTimestamp = GETTIME(); + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->bytesReceived += bufferLen; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics + ->packetsReceived++; // Since every byte buffer translates to a single RTP packet + } } } else { if (ATOMIC_LOAD_BOOL(&pIceAgent->processStun)) { @@ -2567,7 +2607,7 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS if (!pIceCandidatePair->nominated) { CHK_STATUS(getStunAttribute(pStunPacket, STUN_ATTRIBUTE_TYPE_USE_CANDIDATE, &pStunAttr)); if (pStunAttr != NULL) { - DLOGD("received candidate with USE_CANDIDATE flag, local candidate type %s(%s:%s).", + DLOGI("received candidate with USE_CANDIDATE flag, local candidate type %s(%s:%s).", iceAgentGetCandidateTypeStr(pIceCandidatePair->local->iceCandidateType), pIceCandidatePair->local->id, pIceCandidatePair->remote->id); pIceCandidatePair->nominated = TRUE; @@ -2581,9 +2621,11 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } if (pIceCandidatePair == pIceAgent->pDataSendingIceCandidatePair) { - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.requestsReceived += connectivityCheckRequestsReceived; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.responsesSent += connectivityCheckResponsesSent; - pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics.nominated = pIceCandidatePair->nominated; + if (pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->requestsReceived += connectivityCheckRequestsReceived; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->responsesSent += connectivityCheckResponsesSent; + pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics->nominated = pIceCandidatePair->nominated; + } } else { DLOGD("going to change the data sending ice candidate pair."); } @@ -2598,14 +2640,16 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS CHK_WARN(pIceCandidate != NULL, retStatus, "Local candidate with socket %d not found. Dropping STUN binding success response", pSocketConnection->localSocket); - // Update round trip time for serial reflexive candidate - pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalResponsesReceived++; - // Transaction ID count be same for candidates coming from same interface, which means there would only - // be one entry. It is not necessary to update a return sttaus since it is not indicative of a failure - if ((hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime)) == STATUS_SUCCESS) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; - CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); - hashTableGetCount(pIceAgent->requestTimestampDiagnostics, &count); + if (pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex] != NULL) { + // Update round trip time for server reflexive candidate + pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->totalResponsesReceived++; + // Transaction ID count be same for candidates coming from same interface, which means there would only + // be one entry. It is not necessary to update a return sttaus since it is not indicative of a failure + if ((hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime)) == STATUS_SUCCESS) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidate->iceServerIndex]->totalRoundTripTime += GETTIME() - requestSentTime; + CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); + hashTableGetCount(pIceAgent->requestTimestampDiagnostics, &count); + } } CHK_STATUS(deserializeStunPacket(pBuffer, bufferLen, NULL, 0, &pStunPacket)); @@ -2633,8 +2677,10 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS DLOGD("Pair binding response! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); if (hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime) == STATUS_SUCCESS) { pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.currentRoundTripTime = - (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->currentRoundTripTime = + (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + } } else { DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); } @@ -2643,11 +2689,14 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS // Update round trip time and responses received only for relay candidates. if (pIceCandidatePair->local->iceCandidateType == ICE_CANDIDATE_TYPE_RELAYED) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalResponsesReceived++; - retStatus = hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime); - if (hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime) == STATUS_SUCCESS) { - pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; - CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); + if (pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex] != NULL) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalResponsesReceived++; + retStatus = hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime); + if (hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime) == STATUS_SUCCESS) { + pIceAgent->pRtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex]->totalRoundTripTime += + GETTIME() - requestSentTime; + CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); + } } } CHK_STATUS(deserializeStunPacket(pBuffer, bufferLen, (PBYTE) pIceAgent->remotePassword, @@ -2679,17 +2728,20 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; DLOGD("Ice candidate pair %s_%s is connected. Round trip time: %" PRIu64 "ms", pIceCandidatePair->local->id, pIceCandidatePair->remote->id, pIceCandidatePair->roundTripTime / HUNDREDS_OF_NANOS_IN_A_MILLISECOND); - pIceCandidatePair->rtcIceCandidatePairDiagnostics.totalRoundTripTime += - (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; - + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->totalRoundTripTime += + (DOUBLE) (pIceCandidatePair->roundTripTime) / HUNDREDS_OF_NANOS_IN_A_SECOND; + } CHK_STATUS(hashTableRemove(pIceCandidatePair->requestSentTime, checkSum)); } else { DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); } } - pIceCandidatePair->rtcIceCandidatePairDiagnostics.responsesReceived += connectivityCheckResponsesReceived; - pIceCandidatePair->rtcIceCandidatePairDiagnostics.lastResponseTimestamp = GETTIME(); + if (pIceCandidatePair->pRtcIceCandidatePairDiagnostics != NULL) { + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->responsesReceived += connectivityCheckResponsesReceived; + pIceCandidatePair->pRtcIceCandidatePairDiagnostics->lastResponseTimestamp = GETTIME(); + } break; case STUN_PACKET_TYPE_BINDING_INDICATION: diff --git a/src/source/Ice/IceAgent.h b/src/source/Ice/IceAgent.h index 0f82748485..90313fa34b 100644 --- a/src/source/Ice/IceAgent.h +++ b/src/source/Ice/IceAgent.h @@ -80,23 +80,23 @@ typedef struct __IceAgent* PIceAgent; * Internal structure tracking ICE server parameters for diagnostics and metrics/stats */ typedef struct { - CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - INT32 port; //!< Port number used by client - UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server - UINT64 totalResponsesReceived; //!< Total number of responses received from the server - UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received + CHAR url[MAX_ICE_CONFIG_URI_LEN + 1]; //!< STUN/TURN server URL + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + INT32 port; //!< Port number used by client + UINT64 totalRequestsSent; //!< Total amount of requests that have been sent to the server + UINT64 totalResponsesReceived; //!< Total number of responses received from the server + UINT64 totalRoundTripTime; //!< Sum of RTTs of all the requests for which response has been received } RtcIceServerDiagnostics, *PRtcIceServerDiagnostics; typedef struct { - DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained - CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate - CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP - CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. - //!< Valid values: UDP, TCP, TLS - CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate - INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 - INT32 port; //!< Port number of the candidate + DOMString url; //!< For local candidates this is the URL of the ICE server from which the candidate was obtained + CHAR address[KVS_IP_ADDRESS_STRING_BUFFER_LEN]; //!< IPv4 or IPv6 address of the candidate + CHAR protocol[MAX_PROTOCOL_LENGTH + 1]; //!< Valid values: UDP, TCP + CHAR relayProtocol[MAX_PROTOCOL_LENGTH + 1]; //!< Protocol used by endpoint to communicate with TURN server. + //!< Valid values: UDP, TCP, TLS + CHAR candidateType[MAX_CANDIDATE_TYPE_LENGTH + 1]; //!< Type of local/remote ICE candidate + INT32 priority; //!< Computed using the formula in https://tools.ietf.org/html/rfc5245#section-15.1 + INT32 port; //!< Port number of the candidate } RtcIceCandidateDiagnostics, *PRtcIceCandidateDiagnostics; typedef struct { @@ -182,7 +182,7 @@ typedef struct { PHashTable requestSentTime; UINT64 roundTripTime; UINT64 responsesReceived; - RtcIceCandidatePairDiagnostics rtcIceCandidatePairDiagnostics; + PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics; } IceCandidatePair, *PIceCandidatePair; typedef struct { @@ -210,9 +210,9 @@ struct __IceAgent { CHAR remotePassword[MAX_ICE_CONFIG_CREDENTIAL_LEN + 1]; CHAR combinedUserName[(MAX_ICE_CONFIG_USER_NAME_LEN + 1) << 1]; //!< the combination of remote user name and local user name. - RtcIceServerDiagnostics rtcIceServerDiagnostics[MAX_ICE_SERVERS_COUNT]; - RtcIceCandidateDiagnostics rtcSelectedLocalIceCandidateDiagnostics; - RtcIceCandidateDiagnostics rtcSelectedRemoteIceCandidateDiagnostics; + PRtcIceServerDiagnostics pRtcIceServerDiagnostics[MAX_ICE_SERVERS_COUNT]; + PRtcIceCandidateDiagnostics pRtcSelectedLocalIceCandidateDiagnostics; + PRtcIceCandidateDiagnostics pRtcSelectedRemoteIceCandidateDiagnostics; IceAgentProfileDiagnostics iceAgentProfileDiagnostics; PHashTable requestTimestampDiagnostics; diff --git a/src/source/Metrics/Metrics.c b/src/source/Metrics/Metrics.c index f39c3e0292..9ca5aa0a73 100644 --- a/src/source/Metrics/Metrics.c +++ b/src/source/Metrics/Metrics.c @@ -13,37 +13,40 @@ STATUS getIceCandidatePairStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceCa pIceAgent = ((PKvsPeerConnection) pRtcPeerConnection)->pIceAgent; MUTEX_LOCK(pIceAgent->lock); locked = TRUE; + CHK(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS); CHK(pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_SUCCESS); - PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = &pIceAgent->pDataSendingIceCandidatePair->rtcIceCandidatePairDiagnostics; - STRCPY(pRtcIceCandidatePairStats->localCandidateId, pRtcIceCandidatePairDiagnostics->localCandidateId); - STRCPY(pRtcIceCandidatePairStats->remoteCandidateId, pRtcIceCandidatePairDiagnostics->remoteCandidateId); - pRtcIceCandidatePairStats->state = pRtcIceCandidatePairDiagnostics->state; - pRtcIceCandidatePairStats->nominated = pRtcIceCandidatePairDiagnostics->nominated; + PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics; + if (pRtcIceCandidatePairDiagnostics != NULL) { + STRCPY(pRtcIceCandidatePairStats->localCandidateId, pRtcIceCandidatePairDiagnostics->localCandidateId); + STRCPY(pRtcIceCandidatePairStats->remoteCandidateId, pRtcIceCandidatePairDiagnostics->remoteCandidateId); + pRtcIceCandidatePairStats->state = pRtcIceCandidatePairDiagnostics->state; + pRtcIceCandidatePairStats->nominated = pRtcIceCandidatePairDiagnostics->nominated; - // Note: circuitBreakerTriggerCount This is set to NULL currently - pRtcIceCandidatePairStats->circuitBreakerTriggerCount = pRtcIceCandidatePairDiagnostics->circuitBreakerTriggerCount; + // Note: circuitBreakerTriggerCount This is set to NULL currently + pRtcIceCandidatePairStats->circuitBreakerTriggerCount = pRtcIceCandidatePairDiagnostics->circuitBreakerTriggerCount; - pRtcIceCandidatePairStats->packetsDiscardedOnSend = pRtcIceCandidatePairDiagnostics->packetsDiscardedOnSend; - pRtcIceCandidatePairStats->packetsSent = pRtcIceCandidatePairDiagnostics->packetsSent; - pRtcIceCandidatePairStats->packetsReceived = pRtcIceCandidatePairDiagnostics->packetsReceived; + pRtcIceCandidatePairStats->packetsDiscardedOnSend = pRtcIceCandidatePairDiagnostics->packetsDiscardedOnSend; + pRtcIceCandidatePairStats->packetsSent = pRtcIceCandidatePairDiagnostics->packetsSent; + pRtcIceCandidatePairStats->packetsReceived = pRtcIceCandidatePairDiagnostics->packetsReceived; - pRtcIceCandidatePairStats->bytesDiscardedOnSend = pRtcIceCandidatePairDiagnostics->bytesDiscardedOnSend; - pRtcIceCandidatePairStats->bytesSent = pRtcIceCandidatePairDiagnostics->bytesSent; - pRtcIceCandidatePairStats->bytesReceived = pRtcIceCandidatePairDiagnostics->bytesReceived; + pRtcIceCandidatePairStats->bytesDiscardedOnSend = pRtcIceCandidatePairDiagnostics->bytesDiscardedOnSend; + pRtcIceCandidatePairStats->bytesSent = pRtcIceCandidatePairDiagnostics->bytesSent; + pRtcIceCandidatePairStats->bytesReceived = pRtcIceCandidatePairDiagnostics->bytesReceived; - pRtcIceCandidatePairStats->lastPacketSentTimestamp = pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp; - pRtcIceCandidatePairStats->lastPacketReceivedTimestamp = pRtcIceCandidatePairDiagnostics->lastPacketReceivedTimestamp; - pRtcIceCandidatePairStats->lastRequestTimestamp = pRtcIceCandidatePairDiagnostics->lastRequestTimestamp; - pRtcIceCandidatePairStats->firstRequestTimestamp = pRtcIceCandidatePairDiagnostics->firstRequestTimestamp; - pRtcIceCandidatePairStats->lastResponseTimestamp = pRtcIceCandidatePairDiagnostics->lastResponseTimestamp; + pRtcIceCandidatePairStats->lastPacketSentTimestamp = pRtcIceCandidatePairDiagnostics->lastPacketSentTimestamp; + pRtcIceCandidatePairStats->lastPacketReceivedTimestamp = pRtcIceCandidatePairDiagnostics->lastPacketReceivedTimestamp; + pRtcIceCandidatePairStats->lastRequestTimestamp = pRtcIceCandidatePairDiagnostics->lastRequestTimestamp; + pRtcIceCandidatePairStats->firstRequestTimestamp = pRtcIceCandidatePairDiagnostics->firstRequestTimestamp; + pRtcIceCandidatePairStats->lastResponseTimestamp = pRtcIceCandidatePairDiagnostics->lastResponseTimestamp; - pRtcIceCandidatePairStats->totalRoundTripTime = pRtcIceCandidatePairDiagnostics->totalRoundTripTime; - pRtcIceCandidatePairStats->currentRoundTripTime = pRtcIceCandidatePairDiagnostics->currentRoundTripTime; + pRtcIceCandidatePairStats->totalRoundTripTime = pRtcIceCandidatePairDiagnostics->totalRoundTripTime; + pRtcIceCandidatePairStats->currentRoundTripTime = pRtcIceCandidatePairDiagnostics->currentRoundTripTime; - pRtcIceCandidatePairStats->requestsReceived = pRtcIceCandidatePairDiagnostics->requestsReceived; - pRtcIceCandidatePairStats->requestsSent = pRtcIceCandidatePairDiagnostics->requestsSent; - pRtcIceCandidatePairStats->responsesReceived = pRtcIceCandidatePairDiagnostics->responsesReceived; - pRtcIceCandidatePairStats->responsesSent = pRtcIceCandidatePairDiagnostics->responsesSent; + pRtcIceCandidatePairStats->requestsReceived = pRtcIceCandidatePairDiagnostics->requestsReceived; + pRtcIceCandidatePairStats->requestsSent = pRtcIceCandidatePairDiagnostics->requestsSent; + pRtcIceCandidatePairStats->responsesReceived = pRtcIceCandidatePairDiagnostics->responsesReceived; + pRtcIceCandidatePairStats->responsesSent = pRtcIceCandidatePairDiagnostics->responsesSent; + } CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); @@ -59,17 +62,20 @@ STATUS getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote CHK((pRtcPeerConnection != NULL || pRtcIceCandidateStats != NULL), STATUS_NULL_ARG); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedRemoteIceCandidateDiagnostics; - if (!isRemote) { - pRtcIceCandidateDiagnostics = &pIceAgent->rtcSelectedLocalIceCandidateDiagnostics; - STRCPY(pRtcIceCandidateStats->relayProtocol, pRtcIceCandidateDiagnostics->relayProtocol); - STRCPY(pRtcIceCandidateStats->url, pRtcIceCandidateDiagnostics->url); + CHK(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS); + PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; + if (pRtcIceCandidateDiagnostics != NULL) { + if (!isRemote) { + pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics; + STRCPY(pRtcIceCandidateStats->relayProtocol, pRtcIceCandidateDiagnostics->relayProtocol); + STRCPY(pRtcIceCandidateStats->url, pRtcIceCandidateDiagnostics->url); + } + STRCPY(pRtcIceCandidateStats->address, pRtcIceCandidateDiagnostics->address); + STRCPY(pRtcIceCandidateStats->candidateType, pRtcIceCandidateDiagnostics->candidateType); + pRtcIceCandidateStats->port = pRtcIceCandidateDiagnostics->port; + pRtcIceCandidateStats->priority = pRtcIceCandidateDiagnostics->priority; + STRCPY(pRtcIceCandidateStats->protocol, pRtcIceCandidateDiagnostics->protocol); } - STRCPY(pRtcIceCandidateStats->address, pRtcIceCandidateDiagnostics->address); - STRCPY(pRtcIceCandidateStats->candidateType, pRtcIceCandidateDiagnostics->candidateType); - pRtcIceCandidateStats->port = pRtcIceCandidateDiagnostics->port; - pRtcIceCandidateStats->priority = pRtcIceCandidateDiagnostics->priority; - STRCPY(pRtcIceCandidateStats->protocol, pRtcIceCandidateDiagnostics->protocol); CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); @@ -83,16 +89,20 @@ STATUS getIceServerStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceServerSta BOOL locked = FALSE; PIceAgent pIceAgent = ((PKvsPeerConnection) pRtcPeerConnection)->pIceAgent; CHK((pRtcPeerConnection != NULL && pRtcIceServerStats != NULL), STATUS_NULL_ARG); - CHK(pRtcIceServerStats->iceServerIndex < pIceAgent->iceServersCount, STATUS_ICE_SERVER_INDEX_INVALID); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - pRtcIceServerStats->port = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].port; - STRCPY(pRtcIceServerStats->protocol, pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].protocol); - STRCPY(pRtcIceServerStats->url, pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].url); - pRtcIceServerStats->totalRequestsSent = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalRequestsSent; - pRtcIceServerStats->totalResponsesReceived = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalResponsesReceived; - pRtcIceServerStats->totalRoundTripTime = pIceAgent->rtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex].totalRoundTripTime; + CHK(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS); + CHK(pRtcIceServerStats->iceServerIndex < pIceAgent->iceServersCount, STATUS_ICE_SERVER_INDEX_INVALID); + + if (pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex] != NULL) { + pRtcIceServerStats->port = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->port; + STRCPY(pRtcIceServerStats->protocol, pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->protocol); + STRCPY(pRtcIceServerStats->url, pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->url); + pRtcIceServerStats->totalRequestsSent = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalRequestsSent; + pRtcIceServerStats->totalResponsesReceived = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalResponsesReceived; + pRtcIceServerStats->totalRoundTripTime = pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex]->totalRoundTripTime; + } CleanUp: if (locked) { MUTEX_UNLOCK(pIceAgent->lock); From 507fe0da03344238c89e15853aab04beddc1df72 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Fri, 8 Mar 2024 14:39:08 -0800 Subject: [PATCH 07/11] enable flag in samples --- samples/Common.c | 13 ++++++++----- samples/Samples.h | 1 + src/source/Ice/IceAgent.c | 5 ----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/samples/Common.c b/samples/Common.c index a09a70e562..b4094dd7ab 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -51,8 +51,8 @@ VOID onConnectionStateChange(UINT64 customData, RTC_PEER_CONNECTION_STATE newSta CHK_STATUS(peerConnectionGetMetrics(pSampleStreamingSession->pPeerConnection, &pSampleStreamingSession->peerConnectionMetrics)); CHK_STATUS(iceAgentGetMetrics(pSampleStreamingSession->pPeerConnection, &pSampleStreamingSession->iceMetrics)); - if (STATUS_FAILED(retStatus = logSelectedIceCandidatesInformation(pSampleStreamingSession))) { - DLOGW("Failed to get information about selected Ice candidates: 0x%08x", retStatus); + if (pSampleConfiguration->enableIceStats) { + CHK_LOG_ERR(logSelectedIceCandidatesInformation(pSampleStreamingSession)); } break; case RTC_PEER_CONNECTION_STATE_FAILED: @@ -398,7 +398,7 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP // Set the ICE mode explicitly configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL; - configuration.kvsRtcConfiguration.enableIceStats = TRUE; + configuration.kvsRtcConfiguration.enableIceStats = pSampleConfiguration->enableIceStats; // Set the STUN server PCHAR pKinesisVideoStunUrlPostFix = KINESIS_VIDEO_STUN_URL_POSTFIX; @@ -535,6 +535,7 @@ STATUS createSampleStreamingSession(PSampleConfiguration pSampleConfiguration, P ATOMIC_STORE_BOOL(&pSampleStreamingSession->candidateGatheringDone, FALSE); pSampleStreamingSession->peerConnectionMetrics.peerConnectionStats.peerConnectionStartTime = GETTIME() / HUNDREDS_OF_NANOS_IN_A_MILLISECOND; + pSampleConfiguration->enableIceStats = FALSE; CHK_STATUS(initializePeerConnection(pSampleConfiguration, &pSampleStreamingSession->pPeerConnection)); CHK_STATUS(peerConnectionOnIceCandidate(pSampleStreamingSession->pPeerConnection, (UINT64) pSampleStreamingSession, onIceCandidateHandler)); CHK_STATUS( @@ -1204,7 +1205,9 @@ STATUS freeSampleConfiguration(PSampleConfiguration* ppSampleConfiguration) } for (i = 0; i < pSampleConfiguration->streamingSessionCount; ++i) { - CHK_LOG_ERR(gatherIceServerStats(pSampleConfiguration->sampleStreamingSessionList[i])); + if (pSampleConfiguration->enableIceStats) { + CHK_LOG_ERR(gatherIceServerStats(pSampleConfiguration->sampleStreamingSessionList[i])); + } freeSampleStreamingSession(&pSampleConfiguration->sampleStreamingSessionList[i]); } if (locked) { @@ -1535,7 +1538,7 @@ STATUS signalingMessageReceived(UINT64 customData, PReceivedSignalingMessage pRe MUTEX_UNLOCK(pSampleConfiguration->sampleConfigurationObjLock); locked = FALSE; - if (startStats && + if (pSampleConfiguration->enableIceStats && startStats && STATUS_FAILED(retStatus = timerQueueAddTimer(pSampleConfiguration->timerQueueHandle, SAMPLE_STATS_DURATION, SAMPLE_STATS_DURATION, getIceCandidatePairStatsCallback, (UINT64) pSampleConfiguration, &pSampleConfiguration->iceCandidatePairStatsTimerId))) { diff --git a/samples/Samples.h b/samples/Samples.h index 83644c0689..de7413f4d7 100644 --- a/samples/Samples.h +++ b/samples/Samples.h @@ -148,6 +148,7 @@ typedef struct { PCHAR rtspUri; UINT32 logLevel; + BOOL enableIceStats; } SampleConfiguration, *PSampleConfiguration; typedef struct { diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 4a743a1f71..6b819b5210 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -40,11 +40,6 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge CHK(NULL != (pIceAgent = (PIceAgent) MEMCALLOC(1, SIZEOF(IceAgent))), STATUS_NOT_ENOUGH_MEMORY); STRNCPY(pIceAgent->localUsername, username, MAX_ICE_CONFIG_USER_NAME_LEN); STRNCPY(pIceAgent->localPassword, password, MAX_ICE_CONFIG_CREDENTIAL_LEN); - DLOGI("Size of RtcIceServerDiagnostics: %d", SIZEOF(RtcIceServerDiagnostics)); - DLOGI("Size of RtcIceCandidateDiagnostics: %d", SIZEOF(RtcIceCandidateDiagnostics)); - DLOGI("Size of IceAgentProfileDiagnostics: %d", SIZEOF(IceAgentProfileDiagnostics)); - DLOGI("Size of KvsIpAddress: %d", SIZEOF(KvsIpAddress)); - DLOGI("Size of ICE agent: %d", SIZEOF(IceAgent)); ATOMIC_STORE_BOOL(&pIceAgent->remoteCredentialReceived, FALSE); ATOMIC_STORE_BOOL(&pIceAgent->agentStartGathering, FALSE); ATOMIC_STORE_BOOL(&pIceAgent->candidateGatheringFinished, FALSE); From e0230929ecb0cfaa34b758766b5068ea5affbe4d Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Fri, 8 Mar 2024 15:08:52 -0800 Subject: [PATCH 08/11] Add unit test --- src/source/Ice/IceAgent.c | 3 ++- tst/MetricsApiTest.cpp | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 6b819b5210..8df01cbfea 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -165,6 +165,7 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) PIceAgent pIceAgent = NULL; PDoubleListNode pCurNode = NULL; UINT64 data; + UINT32 i; PIceCandidatePair pIceCandidatePair = NULL; PIceCandidate pIceCandidate = NULL; @@ -266,7 +267,7 @@ STATUS freeIceAgent(PIceAgent* ppIceAgent) hashTableFree(pIceAgent->requestTimestampDiagnostics); SAFE_MEMFREE(pIceAgent->pRtcSelectedLocalIceCandidateDiagnostics); SAFE_MEMFREE(pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics); - for (int i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { + for (i = 0; i < MAX_ICE_SERVERS_COUNT; i++) { SAFE_MEMFREE(pIceAgent->pRtcIceServerDiagnostics[i]); } MEMFREE(pIceAgent); diff --git a/tst/MetricsApiTest.cpp b/tst/MetricsApiTest.cpp index 7484d2db94..46db2c245a 100644 --- a/tst/MetricsApiTest.cpp +++ b/tst/MetricsApiTest.cpp @@ -56,7 +56,7 @@ TEST_F(MetricsApiTest, webRtcIceServerGetMetrics) STRNCPY(configuration.iceServers[1].urls, (PCHAR) "turns:54.202.170.151:443?transport=tcp", MAX_ICE_CONFIG_URI_LEN); STRNCPY(configuration.iceServers[1].credential, (PCHAR) "username", MAX_ICE_CONFIG_CREDENTIAL_LEN); STRNCPY(configuration.iceServers[1].username, (PCHAR) "password", MAX_ICE_CONFIG_USER_NAME_LEN); - + configuration.kvsRtcConfiguration.enableIceStats = TRUE; ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); EXPECT_EQ(STATUS_ICE_SERVER_INDEX_INVALID, rtcPeerConnectionGetMetrics(pRtcPeerConnection, NULL, &rtcIceMetrics)); @@ -89,7 +89,7 @@ TEST_F(MetricsApiTest, webRtcIceCandidateGetMetrics) STRNCPY(configuration.iceServers[0].urls, (PCHAR) "stun:stun.kinesisvideo.us-west-2.amazonaws.com:443", MAX_ICE_CONFIG_URI_LEN); STRNCPY(configuration.iceServers[0].credential, (PCHAR) "", MAX_ICE_CONFIG_CREDENTIAL_LEN); STRNCPY(configuration.iceServers[0].username, (PCHAR) "", MAX_ICE_CONFIG_USER_NAME_LEN); - + configuration.kvsRtcConfiguration.enableIceStats = TRUE; ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); pIceAgent = ((PKvsPeerConnection) pRtcPeerConnection)->pIceAgent; @@ -156,6 +156,36 @@ TEST_F(MetricsApiTest, webRtcIceCandidateGetMetrics) EXPECT_EQ(STATUS_SUCCESS, freePeerConnection(&pRtcPeerConnection)); } +TEST_F(MetricsApiTest, webRtcIceServerGetMetrics_IceStatsDisabled) +{ + RtcConfiguration configuration; + PRtcPeerConnection pRtcPeerConnection; + RtcStats rtcIceMetrics; + rtcIceMetrics.requestedTypeOfStats = RTC_STATS_TYPE_ICE_SERVER; // Supplying a type that is unavailable + rtcIceMetrics.rtcStatsObject.iceServerStats.iceServerIndex = 5; + + MEMSET(&configuration, 0x00, SIZEOF(RtcConfiguration)); + MEMSET(&rtcIceMetrics.rtcStatsObject.iceServerStats, 0x00, SIZEOF(RtcIceServerStats)); + STRNCPY(configuration.iceServers[0].urls, (PCHAR) "stun:stun.kinesisvideo.us-west-2.amazonaws.com:443", MAX_ICE_CONFIG_URI_LEN); + STRNCPY(configuration.iceServers[0].credential, (PCHAR) "", MAX_ICE_CONFIG_CREDENTIAL_LEN); + STRNCPY(configuration.iceServers[0].username, (PCHAR) "", MAX_ICE_CONFIG_USER_NAME_LEN); + + STRNCPY(configuration.iceServers[1].urls, (PCHAR) "turns:54.202.170.151:443?transport=tcp", MAX_ICE_CONFIG_URI_LEN); + STRNCPY(configuration.iceServers[1].credential, (PCHAR) "username", MAX_ICE_CONFIG_CREDENTIAL_LEN); + STRNCPY(configuration.iceServers[1].username, (PCHAR) "password", MAX_ICE_CONFIG_USER_NAME_LEN); + configuration.kvsRtcConfiguration.enableIceStats = FALSE; + ASSERT_EQ(STATUS_SUCCESS, createPeerConnection(&configuration, &pRtcPeerConnection)); + + rtcIceMetrics.rtcStatsObject.iceServerStats.iceServerIndex = 1; + EXPECT_EQ(STATUS_SUCCESS, rtcPeerConnectionGetMetrics(pRtcPeerConnection, NULL, &rtcIceMetrics)); + EXPECT_EQ(0, rtcIceMetrics.rtcStatsObject.iceServerStats.port); + EXPECT_EQ('\0', rtcIceMetrics.rtcStatsObject.iceServerStats.url[0]); + EXPECT_EQ('\0', rtcIceMetrics.rtcStatsObject.iceServerStats.protocol[0]); + + EXPECT_EQ(STATUS_SUCCESS, closePeerConnection(pRtcPeerConnection)); + EXPECT_EQ(STATUS_SUCCESS, freePeerConnection(&pRtcPeerConnection)); +} + } // namespace webrtcclient } // namespace video } // namespace kinesis From 84c70fbabdf9bedc87d00f28d456165161371b80 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Fri, 8 Mar 2024 16:13:01 -0800 Subject: [PATCH 09/11] Fix bug --- src/source/Ice/IceAgent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 8df01cbfea..2e91d788c0 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -119,8 +119,8 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge MEMSET(pIceAgent->pRtcIceServerDiagnostics[i]->protocol, 0, SIZEOF(pIceAgent->pRtcIceServerDiagnostics[i]->protocol)); } STRCPY(pIceAgent->pRtcIceServerDiagnostics[i]->url, pRtcConfiguration->iceServers[i].urls); - pIceAgent->iceServersCount++; } + pIceAgent->iceServersCount++; } else { DLOGE("Failed to parse ICE servers"); } From c9a9d437c11d3dd97315a56bf3554547ad5781a1 Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Mon, 11 Mar 2024 11:16:10 -0700 Subject: [PATCH 10/11] README for the flag --- README.md | 10 ++++++++++ src/source/Ice/IceAgent.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7520b9f414..477f222020 100644 --- a/README.md +++ b/README.md @@ -466,6 +466,16 @@ Let us look into when each of these could be changed: 3. `iceConnectionCheckTimeout`: It is useful to increase this timeout in unstable/slow network where the packet exchange takes time and hence the binding request/response. Essentially, increasing it will allow atleast one candidate pair to be tried for nomination by the other peer. 4. `iceConnectionCheckPollingInterval`: This value is set to a default of 50 ms per [spec](https://datatracker.ietf.org/doc/html/rfc8445#section-14.2). Changing this would change the frequency of connectivity checks and essentially, the ICE state machine transitions. Decreasing the value could help in faster connection establishment in a reliable high performant network setting with good system resources. Increasing the value could help in reducing the network load, however, the connection establishment could slow down. Unless there is a strong reasoning, it is **NOT** recommended to deviate from spec/default. +### Enable ICE agent stats + +The SDK calculates 4 different stats: +1. ICE server stats - stats for ICE servers the SDK is using +2. [Local candidate stats](https://www.w3.org/TR/webrtc-stats/#dom-rtcstatstype-local-candidate) - stats for the selected local candidate +3. [Remote candidate stats](https://www.w3.org/TR/webrtc-stats/#dom-rtcstatstype-remote-candidate) - stats for the selected remote candidate +4. [Candidate pair stats](https://www.w3.org/TR/webrtc-stats/#dom-rtcstatstype-candidate-pair) - stats for the selected candidate pair + +The SDK disables generating these stats by default. In order to be enable the SDK to calculate these stats, the application needs to set the following field: +`configuration.kvsRtcConfiguration.enableIceStats = TRUE`. ### Controlling RTP rolling buffer capacity diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 2e91d788c0..7b55dcc5d5 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -87,7 +87,7 @@ STATUS createIceAgent(PCHAR username, PCHAR password, PIceAgentCallbacks pIceAge // Pre-allocate stun packets - // no other attribtues needed: https://tools.ietf.org/html/rfc8445#section-11 + // no other attributes needed: https://tools.ietf.org/html/rfc8445#section-11 CHK_STATUS(createStunPacket(STUN_PACKET_TYPE_BINDING_INDICATION, NULL, &pIceAgent->pBindingIndication)); CHK_STATUS(hashTableCreateWithParams(ICE_HASH_TABLE_BUCKET_COUNT, ICE_HASH_TABLE_BUCKET_LENGTH, &pIceAgent->requestTimestampDiagnostics)); From 563a88cb7eee559039c0dea959086ebac61af3ab Mon Sep 17 00:00:00 2001 From: Divya Sampath Kumar Date: Mon, 11 Mar 2024 13:21:39 -0700 Subject: [PATCH 11/11] Update readme --- README.md | 2 ++ samples/Common.c | 1 + src/source/Ice/IceAgent.c | 6 ++++-- src/source/Metrics/Metrics.c | 6 +++--- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 477f222020..6aa992360a 100644 --- a/README.md +++ b/README.md @@ -474,6 +474,8 @@ The SDK calculates 4 different stats: 3. [Remote candidate stats](https://www.w3.org/TR/webrtc-stats/#dom-rtcstatstype-remote-candidate) - stats for the selected remote candidate 4. [Candidate pair stats](https://www.w3.org/TR/webrtc-stats/#dom-rtcstatstype-candidate-pair) - stats for the selected candidate pair +For more information on these stats, refer to [AWS Docs](https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-reference.html) + The SDK disables generating these stats by default. In order to be enable the SDK to calculate these stats, the application needs to set the following field: `configuration.kvsRtcConfiguration.enableIceStats = TRUE`. diff --git a/samples/Common.c b/samples/Common.c index b4094dd7ab..b8259e8f00 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -535,6 +535,7 @@ STATUS createSampleStreamingSession(PSampleConfiguration pSampleConfiguration, P ATOMIC_STORE_BOOL(&pSampleStreamingSession->candidateGatheringDone, FALSE); pSampleStreamingSession->peerConnectionMetrics.peerConnectionStats.peerConnectionStartTime = GETTIME() / HUNDREDS_OF_NANOS_IN_A_MILLISECOND; + // Flag to enable SDK to calculate selected ice server, local, remote and candidate pair stats. pSampleConfiguration->enableIceStats = FALSE; CHK_STATUS(initializePeerConnection(pSampleConfiguration, &pSampleStreamingSession->pPeerConnection)); CHK_STATUS(peerConnectionOnIceCandidate(pSampleStreamingSession->pPeerConnection, (UINT64) pSampleStreamingSession, onIceCandidateHandler)); diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 7b55dcc5d5..b0dfd05e35 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -1167,8 +1167,10 @@ STATUS createIceCandidatePairs(PIceAgent pIceAgent, PIceCandidate pIceCandidate, pIceCandidatePair = (PIceCandidatePair) MEMCALLOC(1, SIZEOF(IceCandidatePair)); CHK(pIceCandidatePair != NULL, STATUS_NOT_ENOUGH_MEMORY); if (pIceAgent->kvsRtcConfiguration.enableIceStats) { - pIceCandidatePair->pRtcIceCandidatePairDiagnostics = - (PRtcIceCandidatePairDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidatePairDiagnostics)); + CHK(NULL != + (pIceCandidatePair->pRtcIceCandidatePairDiagnostics = + (PRtcIceCandidatePairDiagnostics) MEMCALLOC(1, SIZEOF(RtcIceCandidatePairDiagnostics))), + STATUS_NOT_ENOUGH_MEMORY); } if (isRemoteCandidate) { diff --git a/src/source/Metrics/Metrics.c b/src/source/Metrics/Metrics.c index 9ca5aa0a73..7d4acbc9d9 100644 --- a/src/source/Metrics/Metrics.c +++ b/src/source/Metrics/Metrics.c @@ -13,7 +13,7 @@ STATUS getIceCandidatePairStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceCa pIceAgent = ((PKvsPeerConnection) pRtcPeerConnection)->pIceAgent; MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - CHK(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS); + CHK_WARN(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS, "ICE stats not enabled"); CHK(pIceAgent->pDataSendingIceCandidatePair != NULL, STATUS_SUCCESS); PRtcIceCandidatePairDiagnostics pRtcIceCandidatePairDiagnostics = pIceAgent->pDataSendingIceCandidatePair->pRtcIceCandidatePairDiagnostics; if (pRtcIceCandidatePairDiagnostics != NULL) { @@ -62,7 +62,7 @@ STATUS getIceCandidateStats(PRtcPeerConnection pRtcPeerConnection, BOOL isRemote CHK((pRtcPeerConnection != NULL || pRtcIceCandidateStats != NULL), STATUS_NULL_ARG); MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - CHK(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS); + CHK_WARN(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS, "ICE stats not enabled"); PRtcIceCandidateDiagnostics pRtcIceCandidateDiagnostics = pIceAgent->pRtcSelectedRemoteIceCandidateDiagnostics; if (pRtcIceCandidateDiagnostics != NULL) { if (!isRemote) { @@ -92,7 +92,7 @@ STATUS getIceServerStats(PRtcPeerConnection pRtcPeerConnection, PRtcIceServerSta MUTEX_LOCK(pIceAgent->lock); locked = TRUE; - CHK(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS); + CHK_WARN(pIceAgent->kvsRtcConfiguration.enableIceStats, STATUS_SUCCESS, "ICE stats not enabled"); CHK(pRtcIceServerStats->iceServerIndex < pIceAgent->iceServersCount, STATUS_ICE_SERVER_INDEX_INVALID); if (pIceAgent->pRtcIceServerDiagnostics[pRtcIceServerStats->iceServerIndex] != NULL) {