in src/source/Signaling/LwsApiCalls.c [981:1115]
STATUS getChannelEndpointLws(PSignalingClient pSignalingClient, UINT64 time)
{
ENTERS();
STATUS retStatus = STATUS_SUCCESS;
UNUSED_PARAM(time);
PRequestInfo pRequestInfo = NULL;
CHAR url[MAX_URI_CHAR_LEN + 1];
CHAR paramsJson[MAX_JSON_PARAMETER_STRING_LEN];
UINT32 i, resultLen, strLen, protocolLen = 0, endpointLen = 0;
PCHAR pResponseStr, pProtocol = NULL, pEndpoint = NULL;
PLwsCallInfo pLwsCallInfo = NULL;
jsmn_parser parser;
jsmntok_t tokens[MAX_JSON_TOKEN_COUNT];
UINT32 tokenCount;
BOOL jsonInResourceEndpointList = FALSE, protocol = FALSE, endpoint = FALSE, inEndpointArray = FALSE;
CHK(pSignalingClient != NULL, STATUS_NULL_ARG);
// Create the API url
STRCPY(url, pSignalingClient->pChannelInfo->pControlPlaneUrl);
STRCAT(url, GET_SIGNALING_CHANNEL_ENDPOINT_API_POSTFIX);
// Prepare the json params for the call
SNPRINTF(paramsJson, ARRAY_SIZE(paramsJson), GET_CHANNEL_ENDPOINT_PARAM_JSON_TEMPLATE, pSignalingClient->channelDescription.channelArn,
SIGNALING_CHANNEL_PROTOCOL, getStringFromChannelRoleType(pSignalingClient->pChannelInfo->channelRoleType));
// Create the request info with the body
CHK_STATUS(createRequestInfo(url, paramsJson, pSignalingClient->pChannelInfo->pRegion, pSignalingClient->pChannelInfo->pCertPath, NULL, NULL,
SSL_CERTIFICATE_TYPE_NOT_SPECIFIED, pSignalingClient->pChannelInfo->pUserAgent,
SIGNALING_SERVICE_API_CALL_CONNECTION_TIMEOUT, SIGNALING_SERVICE_API_CALL_COMPLETION_TIMEOUT,
DEFAULT_LOW_SPEED_LIMIT, DEFAULT_LOW_SPEED_TIME_LIMIT, pSignalingClient->pAwsCredentials, &pRequestInfo));
if (pSignalingClient->signalingClientCallbacks.getCurrentTimeFn != NULL) {
pRequestInfo->currentTime = pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData);
}
checkAndCorrectForClockSkew(pSignalingClient, pRequestInfo);
CHK_STATUS(createLwsCallInfo(pSignalingClient, pRequestInfo, PROTOCOL_INDEX_HTTPS, &pLwsCallInfo));
// Make a blocking call
CHK_STATUS(lwsCompleteSync(pLwsCallInfo));
// Set the service call result
ATOMIC_STORE(&pSignalingClient->result, (SIZE_T) pLwsCallInfo->callInfo.callResult);
pResponseStr = pLwsCallInfo->callInfo.responseData;
resultLen = pLwsCallInfo->callInfo.responseDataLen;
// Early return if we have a non-success result
CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL,
STATUS_SIGNALING_LWS_CALL_FAILED);
// Parse and extract the endpoints
jsmn_init(&parser);
tokenCount = jsmn_parse(&parser, pResponseStr, resultLen, tokens, SIZEOF(tokens) / SIZEOF(jsmntok_t));
CHK(tokenCount > 1, STATUS_INVALID_API_CALL_RETURN_JSON);
CHK(tokens[0].type == JSMN_OBJECT, STATUS_INVALID_API_CALL_RETURN_JSON);
pSignalingClient->channelEndpointWss[0] = '\0';
pSignalingClient->channelEndpointHttps[0] = '\0';
// Loop through the tokens and extract the stream description
for (i = 1; i < tokenCount; i++) {
if (!jsonInResourceEndpointList) {
if (compareJsonString(pResponseStr, &tokens[i], JSMN_STRING, (PCHAR) "ResourceEndpointList")) {
jsonInResourceEndpointList = TRUE;
i++;
}
} else {
if (!inEndpointArray && tokens[i].type == JSMN_ARRAY) {
inEndpointArray = TRUE;
} else {
if (tokens[i].type == JSMN_OBJECT) {
// Process if both are set
if (protocol && endpoint) {
if (0 == STRNCMPI(pProtocol, WSS_SCHEME_NAME, protocolLen)) {
STRNCPY(pSignalingClient->channelEndpointWss, pEndpoint, MIN(endpointLen, MAX_SIGNALING_ENDPOINT_URI_LEN));
pSignalingClient->channelEndpointWss[MAX_SIGNALING_ENDPOINT_URI_LEN] = '\0';
} else if (0 == STRNCMPI(pProtocol, HTTPS_SCHEME_NAME, protocolLen)) {
STRNCPY(pSignalingClient->channelEndpointHttps, pEndpoint, MIN(endpointLen, MAX_SIGNALING_ENDPOINT_URI_LEN));
pSignalingClient->channelEndpointHttps[MAX_SIGNALING_ENDPOINT_URI_LEN] = '\0';
}
}
protocol = FALSE;
endpoint = FALSE;
protocolLen = 0;
endpointLen = 0;
pProtocol = NULL;
pEndpoint = NULL;
} else if (compareJsonString(pResponseStr, &tokens[i], JSMN_STRING, (PCHAR) "Protocol")) {
strLen = (UINT32) (tokens[i + 1].end - tokens[i + 1].start);
pProtocol = pResponseStr + tokens[i + 1].start;
protocolLen = strLen;
protocol = TRUE;
i++;
} else if (compareJsonString(pResponseStr, &tokens[i], JSMN_STRING, (PCHAR) "ResourceEndpoint")) {
strLen = (UINT32) (tokens[i + 1].end - tokens[i + 1].start);
CHK(strLen <= MAX_CHANNEL_NAME_LEN, STATUS_INVALID_API_CALL_RETURN_JSON);
pEndpoint = pResponseStr + tokens[i + 1].start;
endpointLen = strLen;
endpoint = TRUE;
i++;
}
}
}
}
// Check if we have unprocessed protocol
if (protocol && endpoint) {
if (0 == STRNCMPI(pProtocol, WSS_SCHEME_NAME, protocolLen)) {
STRNCPY(pSignalingClient->channelEndpointWss, pEndpoint, MIN(endpointLen, MAX_SIGNALING_ENDPOINT_URI_LEN));
pSignalingClient->channelEndpointWss[MAX_SIGNALING_ENDPOINT_URI_LEN] = '\0';
} else if (0 == STRNCMPI(pProtocol, HTTPS_SCHEME_NAME, protocolLen)) {
STRNCPY(pSignalingClient->channelEndpointHttps, pEndpoint, MIN(endpointLen, MAX_SIGNALING_ENDPOINT_URI_LEN));
pSignalingClient->channelEndpointHttps[MAX_SIGNALING_ENDPOINT_URI_LEN] = '\0';
}
}
// Perform some validation on the channel description
CHK(pSignalingClient->channelEndpointHttps[0] != '\0' && pSignalingClient->channelEndpointWss[0] != '\0',
STATUS_SIGNALING_MISSING_ENDPOINTS_IN_GET_ENDPOINT);
CleanUp:
if (STATUS_FAILED(retStatus)) {
DLOGE("Call Failed with Status: 0x%08x", retStatus);
}
freeLwsCallInfo(&pLwsCallInfo);
LEAVES();
return retStatus;
}