blob: 822c77093f53ed274a97708d06f6c7cda09fa2fe [file] [log] [blame]
#include "candidate.h"
#include <rawrtc/ice_candidate.h>
#include <rawrtcc/code.h>
#include <rawrtcc/utils.h>
#include <re.h>
#include <rew.h>
/*
* Get the ICE candidate's foundation.
* `*foundationp` will be set to a copy of the foundation that must be
* unreferenced.
*/
enum rawrtc_code rawrtc_ice_candidate_get_foundation(
char** const foundationp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
// Check arguments
if (!candidate || !foundationp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set copied foundation
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
return rawrtc_strdup(foundationp, candidate->candidate.raw_candidate->foundation);
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
return rawrtc_strdup(
foundationp, candidate->candidate.local_candidate->attr.foundation);
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
return rawrtc_strdup(
foundationp, candidate->candidate.remote_candidate->attr.foundation);
default:
return RAWRTC_CODE_INVALID_STATE;
}
}
/*
* Get the ICE candidate's priority.
*/
enum rawrtc_code rawrtc_ice_candidate_get_priority(
uint32_t* const priorityp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
// Check arguments
if (!candidate || !priorityp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set priority
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
*priorityp = candidate->candidate.raw_candidate->priority;
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
*priorityp = candidate->candidate.local_candidate->attr.prio;
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
*priorityp = candidate->candidate.remote_candidate->attr.prio;
return RAWRTC_CODE_SUCCESS;
default:
return RAWRTC_CODE_INVALID_STATE;
}
}
/*
* Get the ICE candidate's IP address.
* `*ipp` will be set to a copy of the IP address that must be
* unreferenced.
*/
enum rawrtc_code rawrtc_ice_candidate_get_ip(
char** const ipp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
// Check arguments
if (!candidate || !ipp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set copied IP address
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
return rawrtc_strdup(ipp, candidate->candidate.raw_candidate->ip);
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
return rawrtc_sdprintf(ipp, "%j", &candidate->candidate.local_candidate->attr.addr);
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
return rawrtc_sdprintf(ipp, "%j", &candidate->candidate.remote_candidate->attr.addr);
default:
return RAWRTC_CODE_INVALID_STATE;
}
}
/*
* Get the ICE candidate's protocol.
*/
enum rawrtc_code rawrtc_ice_candidate_get_protocol(
enum rawrtc_ice_protocol* const protocolp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
int ipproto;
// Check arguments
if (!candidate || !protocolp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set protocol
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
*protocolp = candidate->candidate.raw_candidate->protocol;
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
ipproto = candidate->candidate.local_candidate->attr.proto;
break;
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
ipproto = candidate->candidate.remote_candidate->attr.proto;
break;
default:
return RAWRTC_CODE_INVALID_STATE;
}
return rawrtc_ipproto_to_ice_protocol(protocolp, ipproto);
}
/*
* Get the ICE candidate's port.
*/
enum rawrtc_code rawrtc_ice_candidate_get_port(
uint16_t* const portp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
// Check arguments
if (!candidate || !portp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set port
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
*portp = candidate->candidate.raw_candidate->port;
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
*portp = sa_port(&candidate->candidate.local_candidate->attr.addr);
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
*portp = sa_port(&candidate->candidate.remote_candidate->attr.addr);
return RAWRTC_CODE_SUCCESS;
default:
return RAWRTC_CODE_INVALID_STATE;
}
}
/*
* Get the ICE candidate's type.
*/
enum rawrtc_code rawrtc_ice_candidate_get_type(
enum rawrtc_ice_candidate_type* typep, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
// Check arguments
if (!candidate || !typep) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set type
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
*typep = candidate->candidate.raw_candidate->type;
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
return rawrtc_ice_cand_type_to_ice_candidate_type(
typep, candidate->candidate.local_candidate->attr.type);
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
return rawrtc_ice_cand_type_to_ice_candidate_type(
typep, candidate->candidate.remote_candidate->attr.type);
default:
return RAWRTC_CODE_INVALID_STATE;
}
}
/*
* Get the ICE candidate's TCP type.
* Return `RAWRTC_CODE_NO_VALUE` in case the protocol is not TCP.
*/
enum rawrtc_code rawrtc_ice_candidate_get_tcp_type(
enum rawrtc_ice_tcp_candidate_type* typep, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
struct ice_cand_attr* re_candidate;
// Check arguments
if (!candidate || !typep) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set type/get re candidate
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
*typep = candidate->candidate.raw_candidate->tcp_type;
return RAWRTC_CODE_SUCCESS;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
re_candidate = &candidate->candidate.local_candidate->attr;
break;
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
re_candidate = &candidate->candidate.remote_candidate->attr;
break;
default:
return RAWRTC_CODE_INVALID_STATE;
}
// Set type from re candidate if TCP
if (re_candidate->proto == IPPROTO_TCP) {
return rawrtc_ice_tcptype_to_ice_tcp_candidate_type(typep, re_candidate->tcptype);
} else {
return RAWRTC_CODE_NO_VALUE;
}
}
/*
* Get the ICE candidate's related IP address.
* `*related_address` will be set to a copy of the related address that
* must be unreferenced.
*
* Return `RAWRTC_CODE_NO_VALUE` in case no related address exists.
*/
enum rawrtc_code rawrtc_ice_candidate_get_related_address(
char** const related_addressp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
struct ice_cand_attr* re_candidate = NULL;
// Check arguments
if (!candidate || !related_addressp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set copied related IP address/get re candidate
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
if (candidate->candidate.raw_candidate->related_address) {
return rawrtc_strdup(
related_addressp, candidate->candidate.raw_candidate->related_address);
}
break;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
re_candidate = &candidate->candidate.local_candidate->attr;
break;
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
re_candidate = &candidate->candidate.remote_candidate->attr;
break;
default:
return RAWRTC_CODE_INVALID_STATE;
}
// Set copied related IP address from re candidate
if (re_candidate && sa_isset(&re_candidate->rel_addr, SA_ADDR)) {
return rawrtc_sdprintf(
related_addressp, "%j", &candidate->candidate.local_candidate->attr.rel_addr);
} else {
return RAWRTC_CODE_NO_VALUE;
}
}
/*
* Get the ICE candidate's related IP address' port.
* `*related_portp` will be set to a copy of the related address'
* port.
*
* Return `RAWRTC_CODE_NO_VALUE` in case no related port exists.
*/
enum rawrtc_code rawrtc_ice_candidate_get_related_port(
uint16_t* const related_portp, // de-referenced
struct rawrtc_ice_candidate* const candidate) {
struct ice_cand_attr* re_candidate = NULL;
// Check arguments
if (!candidate || !related_portp) {
return RAWRTC_CODE_INVALID_ARGUMENT;
}
// Set port
switch (candidate->storage_type) {
case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
if (candidate->candidate.raw_candidate->related_address) {
*related_portp = candidate->candidate.raw_candidate->related_port;
return RAWRTC_CODE_SUCCESS;
}
break;
case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
re_candidate = &candidate->candidate.local_candidate->attr;
break;
case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
re_candidate = &candidate->candidate.remote_candidate->attr;
break;
default:
return RAWRTC_CODE_INVALID_STATE;
}
// Set copied related IP address' port from re candidate
if (re_candidate && sa_isset(&re_candidate->rel_addr, SA_PORT)) {
*related_portp = sa_port(&candidate->candidate.local_candidate->attr.rel_addr);
return RAWRTC_CODE_SUCCESS;
} else {
return RAWRTC_CODE_NO_VALUE;
}
}