You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.8 KiB
172 lines
5.8 KiB
/*****************************************************************************
|
|
* srt_common.c: SRT (Secure Reliable Transport) access module
|
|
*****************************************************************************
|
|
*
|
|
* Copyright (C) 2019, Haivision Systems Inc.
|
|
*
|
|
* Author: Aaron Boxer <aaron.boxer@collabora.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
#include "srt_common.h"
|
|
|
|
const char * const srt_key_length_names[] = { N_( "16 bytes" ), N_(
|
|
"24 bytes" ), N_( "32 bytes" ), };
|
|
|
|
typedef struct parsed_param {
|
|
char *key;
|
|
char *val;
|
|
} parsed_param_t;
|
|
|
|
static inline char*
|
|
find(char *str, char find)
|
|
{
|
|
str = strchr( str, find );
|
|
return str != NULL ? str + 1 : NULL;
|
|
}
|
|
|
|
/**
|
|
* Parse a query string into an array of key/value structs.
|
|
*
|
|
* The query string should be a null terminated string of parameters separated
|
|
* by a delimiter. Each parameter are checked for the equal sign character.
|
|
* If it appears in the parameter, it will be used as a null terminator
|
|
* and the part that comes after it will be the value of the parameter.
|
|
*
|
|
*
|
|
* param: query: the query string to parse. The string will be modified.
|
|
* param: delimiter: the character that separates the key/value pairs
|
|
* from each other.
|
|
* param: params: an array of parsed_param structs to hold the result.
|
|
* param: max_params: maximum number of parameters to parse.
|
|
*
|
|
* Return: the number of parsed items. -1 if there was an error.
|
|
*/
|
|
static int srt_url_parse_query(char *query, const char* delimiter,
|
|
parsed_param_t *params, int max_params)
|
|
{
|
|
int i = 0;
|
|
char *token = NULL;
|
|
|
|
if (!query || *query == '\0')
|
|
return -1;
|
|
if (!params || max_params == 0)
|
|
return 0;
|
|
|
|
token = strtok( query, delimiter );
|
|
while (token != NULL && i < max_params) {
|
|
params[i].key = token;
|
|
params[i].val = NULL;
|
|
if ((params[i].val = strchr( params[i].key, '=' )) != NULL) {
|
|
size_t val_len = strlen( params[i].val );
|
|
|
|
/* make key into a zero-delimited string */
|
|
*(params[i].val) = '\0';
|
|
|
|
/* make sure val is not empty */
|
|
if (val_len > 1) {
|
|
params[i].val++;
|
|
|
|
/* make sure key is not empty */
|
|
if (params[i].key[0])
|
|
i++;
|
|
};
|
|
}
|
|
token = strtok( NULL, delimiter );
|
|
}
|
|
return i;
|
|
}
|
|
|
|
bool srt_parse_url(char* url, srt_params_t* params)
|
|
{
|
|
char* query = NULL;
|
|
struct parsed_param local_params[32];
|
|
int num_params = 0;
|
|
int i = 0;
|
|
bool rc = false;
|
|
|
|
if (!url || !url[0] || !params)
|
|
return false;
|
|
|
|
/* initialize params */
|
|
params->latency = -1;
|
|
params->passphrase = NULL;
|
|
params->key_length = -1;
|
|
params->payload_size = -1;
|
|
params->bandwidth_overhead_limit = -1;
|
|
params->streamid = NULL;
|
|
|
|
/* Parse URL parameters */
|
|
query = find( url, '?' );
|
|
if (query) {
|
|
num_params = srt_url_parse_query( query, "&", local_params,
|
|
sizeof(local_params) / sizeof(struct parsed_param) );
|
|
if (num_params > 0) {
|
|
rc = true;
|
|
for (i = 0; i < num_params; ++i) {
|
|
char* val = local_params[i].val;
|
|
if (!val)
|
|
continue;
|
|
|
|
if (strcmp( local_params[i].key, SRT_PARAM_LATENCY ) == 0) {
|
|
int temp = atoi( val );
|
|
if (temp >= 0)
|
|
params->latency = temp;
|
|
} else if (strcmp( local_params[i].key, SRT_PARAM_PASSPHRASE )
|
|
== 0) {
|
|
params->passphrase = val;
|
|
} else if (strcmp( local_params[i].key, SRT_PARAM_STREAMID )
|
|
== 0) {
|
|
params->streamid = val;
|
|
} else if (strcmp( local_params[i].key, SRT_PARAM_PAYLOAD_SIZE )
|
|
== 0) {
|
|
int temp = atoi( val );
|
|
if (temp >= 0)
|
|
params->payload_size = temp;
|
|
} else if (strcmp( local_params[i].key, SRT_PARAM_KEY_LENGTH )
|
|
== 0) {
|
|
int temp = atoi( val );
|
|
if (temp == srt_key_lengths[0] || temp == srt_key_lengths[1]
|
|
|| temp == srt_key_lengths[2]) {
|
|
params->key_length = temp;
|
|
}
|
|
} else if (strcmp( local_params[i].key,
|
|
SRT_PARAM_BANDWIDTH_OVERHEAD_LIMIT ) == 0) {
|
|
int temp = atoi( val );
|
|
if (temp >= 0)
|
|
params->bandwidth_overhead_limit = temp;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int srt_set_socket_option(vlc_object_t *this, const char *srt_param,
|
|
SRTSOCKET u, SRT_SOCKOPT opt, const void *optval, int optlen)
|
|
{
|
|
int stat = 0;
|
|
|
|
stat = srt_setsockopt( u, 0, opt, optval, optlen );
|
|
if (stat)
|
|
msg_Err( this, "Failed to set socket option %s (reason: %s)", srt_param,
|
|
srt_getlasterror_str() );
|
|
|
|
return stat;
|
|
}
|
|
|
|
|