blob: 822c77093f53ed274a97708d06f6c7cda09fa2fe [file] [log] [blame]
James Kuszmaul4a42b182021-01-17 11:32:46 -08001#include "candidate.h"
2#include <rawrtc/ice_candidate.h>
3#include <rawrtcc/code.h>
4#include <rawrtcc/utils.h>
5#include <re.h>
6#include <rew.h>
7
8/*
9 * Get the ICE candidate's foundation.
10 * `*foundationp` will be set to a copy of the foundation that must be
11 * unreferenced.
12 */
13enum rawrtc_code rawrtc_ice_candidate_get_foundation(
14 char** const foundationp, // de-referenced
15 struct rawrtc_ice_candidate* const candidate) {
16 // Check arguments
17 if (!candidate || !foundationp) {
18 return RAWRTC_CODE_INVALID_ARGUMENT;
19 }
20
21 // Set copied foundation
22 switch (candidate->storage_type) {
23 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
24 return rawrtc_strdup(foundationp, candidate->candidate.raw_candidate->foundation);
25 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
26 return rawrtc_strdup(
27 foundationp, candidate->candidate.local_candidate->attr.foundation);
28 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
29 return rawrtc_strdup(
30 foundationp, candidate->candidate.remote_candidate->attr.foundation);
31 default:
32 return RAWRTC_CODE_INVALID_STATE;
33 }
34}
35
36/*
37 * Get the ICE candidate's priority.
38 */
39enum rawrtc_code rawrtc_ice_candidate_get_priority(
40 uint32_t* const priorityp, // de-referenced
41 struct rawrtc_ice_candidate* const candidate) {
42 // Check arguments
43 if (!candidate || !priorityp) {
44 return RAWRTC_CODE_INVALID_ARGUMENT;
45 }
46
47 // Set priority
48 switch (candidate->storage_type) {
49 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
50 *priorityp = candidate->candidate.raw_candidate->priority;
51 return RAWRTC_CODE_SUCCESS;
52 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
53 *priorityp = candidate->candidate.local_candidate->attr.prio;
54 return RAWRTC_CODE_SUCCESS;
55 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
56 *priorityp = candidate->candidate.remote_candidate->attr.prio;
57 return RAWRTC_CODE_SUCCESS;
58 default:
59 return RAWRTC_CODE_INVALID_STATE;
60 }
61}
62
63/*
64 * Get the ICE candidate's IP address.
65 * `*ipp` will be set to a copy of the IP address that must be
66 * unreferenced.
67 */
68enum rawrtc_code rawrtc_ice_candidate_get_ip(
69 char** const ipp, // de-referenced
70 struct rawrtc_ice_candidate* const candidate) {
71 // Check arguments
72 if (!candidate || !ipp) {
73 return RAWRTC_CODE_INVALID_ARGUMENT;
74 }
75
76 // Set copied IP address
77 switch (candidate->storage_type) {
78 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
79 return rawrtc_strdup(ipp, candidate->candidate.raw_candidate->ip);
80 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
81 return rawrtc_sdprintf(ipp, "%j", &candidate->candidate.local_candidate->attr.addr);
82 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
83 return rawrtc_sdprintf(ipp, "%j", &candidate->candidate.remote_candidate->attr.addr);
84 default:
85 return RAWRTC_CODE_INVALID_STATE;
86 }
87}
88
89/*
90 * Get the ICE candidate's protocol.
91 */
92enum rawrtc_code rawrtc_ice_candidate_get_protocol(
93 enum rawrtc_ice_protocol* const protocolp, // de-referenced
94 struct rawrtc_ice_candidate* const candidate) {
95 int ipproto;
96
97 // Check arguments
98 if (!candidate || !protocolp) {
99 return RAWRTC_CODE_INVALID_ARGUMENT;
100 }
101
102 // Set protocol
103 switch (candidate->storage_type) {
104 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
105 *protocolp = candidate->candidate.raw_candidate->protocol;
106 return RAWRTC_CODE_SUCCESS;
107 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
108 ipproto = candidate->candidate.local_candidate->attr.proto;
109 break;
110 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
111 ipproto = candidate->candidate.remote_candidate->attr.proto;
112 break;
113 default:
114 return RAWRTC_CODE_INVALID_STATE;
115 }
116 return rawrtc_ipproto_to_ice_protocol(protocolp, ipproto);
117}
118
119/*
120 * Get the ICE candidate's port.
121 */
122enum rawrtc_code rawrtc_ice_candidate_get_port(
123 uint16_t* const portp, // de-referenced
124 struct rawrtc_ice_candidate* const candidate) {
125 // Check arguments
126 if (!candidate || !portp) {
127 return RAWRTC_CODE_INVALID_ARGUMENT;
128 }
129
130 // Set port
131 switch (candidate->storage_type) {
132 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
133 *portp = candidate->candidate.raw_candidate->port;
134 return RAWRTC_CODE_SUCCESS;
135 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
136 *portp = sa_port(&candidate->candidate.local_candidate->attr.addr);
137 return RAWRTC_CODE_SUCCESS;
138 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
139 *portp = sa_port(&candidate->candidate.remote_candidate->attr.addr);
140 return RAWRTC_CODE_SUCCESS;
141 default:
142 return RAWRTC_CODE_INVALID_STATE;
143 }
144}
145
146/*
147 * Get the ICE candidate's type.
148 */
149enum rawrtc_code rawrtc_ice_candidate_get_type(
150 enum rawrtc_ice_candidate_type* typep, // de-referenced
151 struct rawrtc_ice_candidate* const candidate) {
152 // Check arguments
153 if (!candidate || !typep) {
154 return RAWRTC_CODE_INVALID_ARGUMENT;
155 }
156
157 // Set type
158 switch (candidate->storage_type) {
159 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
160 *typep = candidate->candidate.raw_candidate->type;
161 return RAWRTC_CODE_SUCCESS;
162 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
163 return rawrtc_ice_cand_type_to_ice_candidate_type(
164 typep, candidate->candidate.local_candidate->attr.type);
165 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
166 return rawrtc_ice_cand_type_to_ice_candidate_type(
167 typep, candidate->candidate.remote_candidate->attr.type);
168 default:
169 return RAWRTC_CODE_INVALID_STATE;
170 }
171}
172
173/*
174 * Get the ICE candidate's TCP type.
175 * Return `RAWRTC_CODE_NO_VALUE` in case the protocol is not TCP.
176 */
177enum rawrtc_code rawrtc_ice_candidate_get_tcp_type(
178 enum rawrtc_ice_tcp_candidate_type* typep, // de-referenced
179 struct rawrtc_ice_candidate* const candidate) {
180 struct ice_cand_attr* re_candidate;
181
182 // Check arguments
183 if (!candidate || !typep) {
184 return RAWRTC_CODE_INVALID_ARGUMENT;
185 }
186
187 // Set type/get re candidate
188 switch (candidate->storage_type) {
189 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
190 *typep = candidate->candidate.raw_candidate->tcp_type;
191 return RAWRTC_CODE_SUCCESS;
192 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
193 re_candidate = &candidate->candidate.local_candidate->attr;
194 break;
195 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
196 re_candidate = &candidate->candidate.remote_candidate->attr;
197 break;
198 default:
199 return RAWRTC_CODE_INVALID_STATE;
200 }
201
202 // Set type from re candidate if TCP
203 if (re_candidate->proto == IPPROTO_TCP) {
204 return rawrtc_ice_tcptype_to_ice_tcp_candidate_type(typep, re_candidate->tcptype);
205 } else {
206 return RAWRTC_CODE_NO_VALUE;
207 }
208}
209
210/*
211 * Get the ICE candidate's related IP address.
212 * `*related_address` will be set to a copy of the related address that
213 * must be unreferenced.
214 *
215 * Return `RAWRTC_CODE_NO_VALUE` in case no related address exists.
216 */
217enum rawrtc_code rawrtc_ice_candidate_get_related_address(
218 char** const related_addressp, // de-referenced
219 struct rawrtc_ice_candidate* const candidate) {
220 struct ice_cand_attr* re_candidate = NULL;
221
222 // Check arguments
223 if (!candidate || !related_addressp) {
224 return RAWRTC_CODE_INVALID_ARGUMENT;
225 }
226
227 // Set copied related IP address/get re candidate
228 switch (candidate->storage_type) {
229 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
230 if (candidate->candidate.raw_candidate->related_address) {
231 return rawrtc_strdup(
232 related_addressp, candidate->candidate.raw_candidate->related_address);
233 }
234 break;
235 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
236 re_candidate = &candidate->candidate.local_candidate->attr;
237 break;
238 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
239 re_candidate = &candidate->candidate.remote_candidate->attr;
240 break;
241 default:
242 return RAWRTC_CODE_INVALID_STATE;
243 }
244
245 // Set copied related IP address from re candidate
246 if (re_candidate && sa_isset(&re_candidate->rel_addr, SA_ADDR)) {
247 return rawrtc_sdprintf(
248 related_addressp, "%j", &candidate->candidate.local_candidate->attr.rel_addr);
249 } else {
250 return RAWRTC_CODE_NO_VALUE;
251 }
252}
253
254/*
255 * Get the ICE candidate's related IP address' port.
256 * `*related_portp` will be set to a copy of the related address'
257 * port.
258 *
259 * Return `RAWRTC_CODE_NO_VALUE` in case no related port exists.
260 */
261enum rawrtc_code rawrtc_ice_candidate_get_related_port(
262 uint16_t* const related_portp, // de-referenced
263 struct rawrtc_ice_candidate* const candidate) {
264 struct ice_cand_attr* re_candidate = NULL;
265
266 // Check arguments
267 if (!candidate || !related_portp) {
268 return RAWRTC_CODE_INVALID_ARGUMENT;
269 }
270
271 // Set port
272 switch (candidate->storage_type) {
273 case RAWRTC_ICE_CANDIDATE_STORAGE_RAW:
274 if (candidate->candidate.raw_candidate->related_address) {
275 *related_portp = candidate->candidate.raw_candidate->related_port;
276 return RAWRTC_CODE_SUCCESS;
277 }
278 break;
279 case RAWRTC_ICE_CANDIDATE_STORAGE_LCAND:
280 re_candidate = &candidate->candidate.local_candidate->attr;
281 break;
282 case RAWRTC_ICE_CANDIDATE_STORAGE_RCAND:
283 re_candidate = &candidate->candidate.remote_candidate->attr;
284 break;
285 default:
286 return RAWRTC_CODE_INVALID_STATE;
287 }
288
289 // Set copied related IP address' port from re candidate
290 if (re_candidate && sa_isset(&re_candidate->rel_addr, SA_PORT)) {
291 *related_portp = sa_port(&candidate->candidate.local_candidate->attr.rel_addr);
292 return RAWRTC_CODE_SUCCESS;
293 } else {
294 return RAWRTC_CODE_NO_VALUE;
295 }
296}