Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMake/Dependencies/libkvsCommonLws-CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ include(ExternalProject)

ExternalProject_Add(libkvsCommonLws-download
GIT_REPOSITORY https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git
GIT_TAG v1.5.4
GIT_TAG dual-stack-support
GIT_PROGRESS TRUE
GIT_SHALLOW TRUE
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/build
Expand Down
1 change: 1 addition & 0 deletions CMake/Dependencies/libwebsockets-CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ ExternalProject_Add(project_libwebsockets
-DLWS_EXT_PTHREAD_LIBRARIES=${LWS_EXT_PTHREAD_LIBRARIES}
-DLWS_OPENSSL_INCLUDE_DIRS=${LWS_OPENSSL_INCLUDE_DIRS}
-DLWS_OPENSSL_LIBRARIES=${LWS_OPENSSL_LIBRARIES}
-DLWS_WITH_IPV6=ON
BUILD_ALWAYS TRUE
TEST_COMMAND ""
)
80 changes: 66 additions & 14 deletions samples/Common.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,26 @@ VOID onIceCandidateHandler(UINT64 customData, PCHAR candidateJson)
CHK_LOG_ERR(retStatus);
}


// Using for testing purposes to filter out tcp and turns cases.
BOOL isTurnUdp(const char* url) {
size_t len = STRLEN(url);
if (len < 7) return FALSE;

// Check start: "turn:"
if (STRNCMP(url, "turn:", 5) != 0) {
return FALSE;
}

// Check end: "udp"
if (STRCMP(url + len - 3, "udp") != 0) {
return FALSE;
}

return TRUE;
}


STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcPeerConnection* ppRtcPeerConnection)
{
ENTERS();
Expand All @@ -363,7 +383,7 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP
configuration.kvsRtcConfiguration.iceSetInterfaceFilterFunc = NULL;

// Set the ICE mode explicitly
configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_ALL;
configuration.iceTransportPolicy = ICE_TRANSPORT_POLICY_RELAY;

#ifdef ENABLE_STATS_CALCULATION_CONTROL
configuration.kvsRtcConfiguration.enableIceStats = pSampleConfiguration->enableIceStats;
Expand All @@ -379,7 +399,7 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP
pKinesisVideoStunUrlPostFix);

if (pSampleConfiguration->useTurn) {
// Set the URIs from the configuration
// // Set the URIs from the configuration
CHK_STATUS(signalingClientGetIceConfigInfoCount(pSampleConfiguration->signalingClientHandle, &iceConfigCount));

/* signalingClientGetIceConfigInfoCount can return more than one turn server. Use only one to optimize
Expand All @@ -398,13 +418,28 @@ STATUS initializePeerConnection(PSampleConfiguration pSampleConfiguration, PRtcP
* It's recommended to not pass too many TURN iceServers to configuration because it will slow down ice gathering in non-trickle mode.
*/

STRNCPY(configuration.iceServers[uriCount + 1].urls, pIceConfigInfo->uris[j], MAX_ICE_CONFIG_URI_LEN);
STRNCPY(configuration.iceServers[uriCount + 1].credential, pIceConfigInfo->password, MAX_ICE_CONFIG_CREDENTIAL_LEN);
STRNCPY(configuration.iceServers[uriCount + 1].username, pIceConfigInfo->userName, MAX_ICE_CONFIG_USER_NAME_LEN);
DLOGD("Ice server %d urls: %s", j + 1, pIceConfigInfo->uris[j]);
DLOGD("Ice server %d username: %s", j + 1, pIceConfigInfo->password);
DLOGD("Ice server %d credential: %s", j + 1, pIceConfigInfo->userName);

if (isTurnUdp(pIceConfigInfo->uris[j])) {
DLOGD("Adding ICE server");
STRNCPY(configuration.iceServers[uriCount + 1].urls, pIceConfigInfo->uris[j], MAX_ICE_CONFIG_URI_LEN);
STRNCPY(configuration.iceServers[uriCount + 1].credential, pIceConfigInfo->password, MAX_ICE_CONFIG_CREDENTIAL_LEN);
STRNCPY(configuration.iceServers[uriCount + 1].username, pIceConfigInfo->userName, MAX_ICE_CONFIG_USER_NAME_LEN);

uriCount++;
}


uriCount++;
}
}

// For testing purposes:
// STRNCPY(configuration.iceServers[1].urls, "turn:[XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]?transport=udp", MAX_ICE_CONFIG_URI_LEN);
// STRNCPY(configuration.iceServers[1].urls, "turn:XXX.XXX.XXX.XXX:XXXX?transport=udp", MAX_ICE_CONFIG_URI_LEN);
// STRNCPY(configuration.iceServers[1].credential, "XXXXXXXX", MAX_ICE_CONFIG_CREDENTIAL_LEN);
// STRNCPY(configuration.iceServers[1].username, "XXXXXXXX", MAX_ICE_CONFIG_USER_NAME_LEN);
}

pSampleConfiguration->iceUriCount = uriCount + 1;
Expand Down Expand Up @@ -794,14 +829,13 @@ STATUS lookForSslCert(PSampleConfiguration* ppSampleConfiguration)
return retStatus;
}

STATUS createSampleConfiguration(PCHAR channelName, SIGNALING_CHANNEL_ROLE_TYPE roleType, BOOL trickleIce, BOOL useTurn, UINT32 logLevel,
PSampleConfiguration* ppSampleConfiguration)
STATUS createSampleConfiguration(PCreateSampleConfigurationParams pCreateSampleConfigurationParams, PSampleConfiguration* ppSampleConfiguration)
{
STATUS retStatus = STATUS_SUCCESS;
PCHAR pAccessKey, pSecretKey, pSessionToken;
PSampleConfiguration pSampleConfiguration = NULL;

CHK(ppSampleConfiguration != NULL, STATUS_NULL_ARG);
CHK(ppSampleConfiguration != NULL && pCreateSampleConfigurationParams != NULL, STATUS_NULL_ARG);

CHK(NULL != (pSampleConfiguration = (PSampleConfiguration) MEMCALLOC(1, SIZEOF(SampleConfiguration))), STATUS_NOT_ENOUGH_MEMORY);

Expand Down Expand Up @@ -870,23 +904,41 @@ STATUS createSampleConfiguration(PCHAR channelName, SIGNALING_CHANNEL_ROLE_TYPE
pSampleConfiguration->signalingSendMessageLock = MUTEX_CREATE(FALSE);
/* This is ignored for master. Master can extract the info from offer. Viewer has to know if peer can trickle or
* not ahead of time. */
pSampleConfiguration->trickleIce = trickleIce;
pSampleConfiguration->useTurn = useTurn;
pSampleConfiguration->trickleIce = pCreateSampleConfigurationParams->trickleIce;
pSampleConfiguration->useTurn = pCreateSampleConfigurationParams->useTurn;
pSampleConfiguration->enableSendingMetricsToViewerViaDc = FALSE;
pSampleConfiguration->receiveAudioVideoSource = NULL;

pSampleConfiguration->channelInfo.version = CHANNEL_INFO_CURRENT_VERSION;
pSampleConfiguration->channelInfo.pChannelName = channelName;
pSampleConfiguration->channelInfo.pChannelName = pCreateSampleConfigurationParams->channelName;
#ifdef IOT_CORE_ENABLE_CREDENTIALS
if ((pIotCoreCertificateId = GETENV(IOT_CORE_CERTIFICATE_ID)) != NULL) {
pSampleConfiguration->channelInfo.pChannelName = pIotCoreCertificateId;
}
#endif

if (pCreateSampleConfigurationParams->useDualStackEndpoints) {
// Create the custom fully qualified control plane endpoint, sans the legacy/dual-stack postfix.
SNPRINTF(pSampleConfiguration->customControlPlaneEndpoint, MAX_CONTROL_PLANE_URI_CHAR_LEN, "%s%s.%s", CONTROL_PLANE_URI_PREFIX,
KINESIS_VIDEO_SERVICE_NAME, pSampleConfiguration->channelInfo.pRegion);

if (STRSTR(pSampleConfiguration->channelInfo.pRegion, "cn-")) {
STRCAT(pSampleConfiguration->customControlPlaneEndpoint,
CONTROL_PLANE_URI_POSTFIX_CN_DUAL_STACK); // Will use CN region dual-stack endpoint.
} else {
STRCAT(pSampleConfiguration->customControlPlaneEndpoint, CONTROL_PLANE_URI_POSTFIX_DUAL_STACK); // Will use Dual-stack endpoint.
}

pSampleConfiguration->channelInfo.pControlPlaneUrl = pSampleConfiguration->customControlPlaneEndpoint;
} else {
pSampleConfiguration->channelInfo.pControlPlaneUrl = NULL; // Will use default legacy endpoints.
}

pSampleConfiguration->channelInfo.pKmsKeyId = NULL;
pSampleConfiguration->channelInfo.tagCount = 0;
pSampleConfiguration->channelInfo.pTags = NULL;
pSampleConfiguration->channelInfo.channelType = SIGNALING_CHANNEL_TYPE_SINGLE_MASTER;
pSampleConfiguration->channelInfo.channelRoleType = roleType;
pSampleConfiguration->channelInfo.channelRoleType = pCreateSampleConfigurationParams->roleType;
pSampleConfiguration->channelInfo.cachingPolicy = SIGNALING_API_CALL_CACHE_TYPE_FILE;
pSampleConfiguration->channelInfo.cachingPeriod = SIGNALING_API_CALL_CACHE_TTL_SENTINEL_VALUE;
pSampleConfiguration->channelInfo.asyncIceServerConfig = TRUE; // has no effect
Expand All @@ -901,7 +953,7 @@ STATUS createSampleConfiguration(PCHAR channelName, SIGNALING_CHANNEL_ROLE_TYPE
pSampleConfiguration->signalingClientCallbacks.customData = (UINT64) pSampleConfiguration;

pSampleConfiguration->clientInfo.version = SIGNALING_CLIENT_INFO_CURRENT_VERSION;
pSampleConfiguration->clientInfo.loggingLevel = logLevel;
pSampleConfiguration->clientInfo.loggingLevel = pCreateSampleConfigurationParams->logLevel;
pSampleConfiguration->clientInfo.cacheFilePath = NULL; // Use the default path
pSampleConfiguration->clientInfo.signalingClientCreationMaxRetryAttempts = CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS_SENTINEL_VALUE;
pSampleConfiguration->iceCandidatePairStatsTimerId = MAX_UINT32;
Expand Down
13 changes: 12 additions & 1 deletion samples/Samples.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ typedef struct {
UINT64 prevTs;
} RtcMetricsHistory, *PRtcMetricsHistory;

typedef struct {
PCHAR channelName;
SIGNALING_CHANNEL_ROLE_TYPE roleType;
BOOL trickleIce;
BOOL useTurn;
BOOL useDualStackEndpoints;
UINT32 logLevel;
} CreateSampleConfigurationParams, *PCreateSampleConfigurationParams;

typedef struct {
volatile ATOMIC_BOOL appTerminateFlag;
volatile ATOMIC_BOOL interrupted;
Expand Down Expand Up @@ -176,6 +185,8 @@ typedef struct {
UINT32 logLevel;
BOOL enableTwcc;
BOOL enableIceStats;
BOOL useDualStackEndpoints;
CHAR customControlPlaneEndpoint[MAX_CONTROL_PLANE_URI_CHAR_LEN];
} SampleConfiguration, *PSampleConfiguration;

typedef struct {
Expand Down Expand Up @@ -247,7 +258,7 @@ PVOID sampleReceiveAudioVideoFrame(PVOID);
PVOID getPeriodicIceCandidatePairStats(PVOID);
STATUS getIceCandidatePairStatsCallback(UINT32, UINT64, UINT64);
STATUS pregenerateCertTimerCallback(UINT32, UINT64, UINT64);
STATUS createSampleConfiguration(PCHAR, SIGNALING_CHANNEL_ROLE_TYPE, BOOL, BOOL, UINT32, PSampleConfiguration*);
STATUS createSampleConfiguration(PCreateSampleConfigurationParams, PSampleConfiguration*);
STATUS freeSampleConfiguration(PSampleConfiguration*);
STATUS signalingClientStateChanged(UINT64, SIGNALING_CLIENT_STATE);
STATUS signalingMessageReceived(UINT64, PReceivedSignalingMessage);
Expand Down
10 changes: 9 additions & 1 deletion samples/kvsWebRTCClientMaster.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ INT32 main(INT32 argc, CHAR* argv[])
signalingClientMetrics.version = SIGNALING_CLIENT_METRICS_CURRENT_VERSION;
RTC_CODEC audioCodec = RTC_CODEC_OPUS;
RTC_CODEC videoCodec = RTC_CODEC_H264_PROFILE_42E01F_LEVEL_ASYMMETRY_ALLOWED_PACKETIZATION_MODE;
CreateSampleConfigurationParams createSampleConfigurationParams;

SET_INSTRUMENTED_ALLOCATORS();
UINT32 logLevel = setLogLevel();
Expand All @@ -27,7 +28,14 @@ INT32 main(INT32 argc, CHAR* argv[])
pChannelName = argc > 1 ? argv[1] : SAMPLE_CHANNEL_NAME;
#endif

CHK_STATUS(createSampleConfiguration(pChannelName, SIGNALING_CHANNEL_ROLE_TYPE_MASTER, TRUE, TRUE, logLevel, &pSampleConfiguration));
createSampleConfigurationParams.channelName = pChannelName;
createSampleConfigurationParams.roleType = SIGNALING_CHANNEL_ROLE_TYPE_MASTER;
createSampleConfigurationParams.trickleIce = TRUE;
createSampleConfigurationParams.useTurn = TRUE;
createSampleConfigurationParams.useDualStackEndpoints = FALSE;
createSampleConfigurationParams.logLevel = logLevel;

CHK_STATUS(createSampleConfiguration(&createSampleConfigurationParams, &pSampleConfiguration));

if (argc > 3) {
if (!STRCMP(argv[3], AUDIO_CODEC_NAME_OPUS)) {
Expand Down
10 changes: 9 additions & 1 deletion samples/kvsWebRTCClientViewer.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ INT32 main(INT32 argc, CHAR* argv[])
BOOL locked = FALSE;
PCHAR pChannelName;
CHAR clientId[256];
CreateSampleConfigurationParams createSampleConfigurationParams;

SET_INSTRUMENTED_ALLOCATORS();
UINT32 logLevel = setLogLevel();
Expand Down Expand Up @@ -81,7 +82,14 @@ INT32 main(INT32 argc, CHAR* argv[])
}
}

CHK_STATUS(createSampleConfiguration(pChannelName, SIGNALING_CHANNEL_ROLE_TYPE_VIEWER, TRUE, TRUE, logLevel, &pSampleConfiguration));
createSampleConfigurationParams.channelName = pChannelName;
createSampleConfigurationParams.roleType = SIGNALING_CHANNEL_ROLE_TYPE_VIEWER;
createSampleConfigurationParams.trickleIce = TRUE;
createSampleConfigurationParams.useTurn = TRUE;
createSampleConfigurationParams.useDualStackEndpoints = FALSE;
createSampleConfigurationParams.logLevel = logLevel;

CHK_STATUS(createSampleConfiguration(&createSampleConfigurationParams, &pSampleConfiguration));
pSampleConfiguration->mediaType = SAMPLE_STREAMING_AUDIO_VIDEO;
pSampleConfiguration->audioCodec = audioCodec;
pSampleConfiguration->videoCodec = videoCodec;
Expand Down
10 changes: 9 additions & 1 deletion samples/kvsWebRTCClientViewerGstSample.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ INT32 main(INT32 argc, CHAR* argv[])
BOOL locked = FALSE;
PCHAR pChannelName;
CHAR clientId[256];
CreateSampleConfigurationParams createSampleConfigurationParams;

SET_INSTRUMENTED_ALLOCATORS();
UINT32 logLevel = setLogLevel();
Expand Down Expand Up @@ -75,7 +76,14 @@ INT32 main(INT32 argc, CHAR* argv[])
}
}

CHK_STATUS(createSampleConfiguration(pChannelName, SIGNALING_CHANNEL_ROLE_TYPE_VIEWER, TRUE, TRUE, logLevel, &pSampleConfiguration));
createSampleConfigurationParams.channelName = pChannelName;
createSampleConfigurationParams.roleType = SIGNALING_CHANNEL_ROLE_TYPE_VIEWER;
createSampleConfigurationParams.trickleIce = TRUE;
createSampleConfigurationParams.useTurn = TRUE;
createSampleConfigurationParams.useDualStackEndpoints = FALSE;
createSampleConfigurationParams.logLevel = logLevel;

CHK_STATUS(createSampleConfiguration(&createSampleConfigurationParams, &pSampleConfiguration));
pSampleConfiguration->mediaType = SAMPLE_STREAMING_AUDIO_VIDEO;
pSampleConfiguration->receiveAudioVideoSource = receiveGstreamerAudioVideo;
pSampleConfiguration->audioCodec = audioCodec;
Expand Down
10 changes: 9 additions & 1 deletion samples/kvsWebrtcClientMasterGstSample.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ INT32 main(INT32 argc, CHAR* argv[])
PCHAR pChannelName;
RTC_CODEC audioCodec = RTC_CODEC_OPUS;
RTC_CODEC videoCodec = RTC_CODEC_H264_PROFILE_42E01F_LEVEL_ASYMMETRY_ALLOWED_PACKETIZATION_MODE;
CreateSampleConfigurationParams createSampleConfigurationParams;

SET_INSTRUMENTED_ALLOCATORS();
UINT32 logLevel = setLogLevel();
Expand All @@ -372,7 +373,14 @@ INT32 main(INT32 argc, CHAR* argv[])
pChannelName = argc > 1 ? argv[1] : SAMPLE_CHANNEL_NAME;
#endif

CHK_STATUS(createSampleConfiguration(pChannelName, SIGNALING_CHANNEL_ROLE_TYPE_MASTER, TRUE, TRUE, logLevel, &pSampleConfiguration));
createSampleConfigurationParams.channelName = pChannelName;
createSampleConfigurationParams.roleType = SIGNALING_CHANNEL_ROLE_TYPE_MASTER;
createSampleConfigurationParams.trickleIce = TRUE;
createSampleConfigurationParams.useTurn = TRUE;
createSampleConfigurationParams.useDualStackEndpoints = FALSE;
createSampleConfigurationParams.logLevel = logLevel;

CHK_STATUS(createSampleConfiguration(&createSampleConfigurationParams, &pSampleConfiguration));

if (argc > 3 && STRCMP(argv[3], "testsrc") == 0) {
if (argc > 4) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,11 @@ extern "C" {
*/
#define MAX_SIGNALING_ENDPOINT_URI_LEN 512

/**
* Maximum allowed Control Plane URI length
*/
#define MAX_CONTROL_PLANE_URI_CHAR_LEN 256

/**
* Maximum allowed correlation ID length
*/
Expand Down
Loading
Loading