blob: d6376fb2898a246d652443a892be2fc214daf482 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file ice/util.c ICE Utilities
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <string.h>
7#ifdef HAVE_SYS_TIME_H
8#include <sys/time.h>
9#endif
10#ifndef WIN32
11#include <time.h>
12#endif
13#include <re_types.h>
14#include <re_fmt.h>
15#include <re_mem.h>
16#include <re_mbuf.h>
17#include <re_list.h>
18#include <re_tmr.h>
19#include <re_sa.h>
20#include <re_stun.h>
21#include <re_sys.h>
22#include <re_ice.h>
23#include "ice.h"
24
25
26#define DEBUG_MODULE "iceutil"
27#define DEBUG_LEVEL 5
28#include <re_dbg.h>
29
30
31enum {
32 CAND_PRIO_RELAY = 0,
33 CAND_PRIO_SRFLX = 100,
34 CAND_PRIO_PRFLX = 110,
35 CAND_PRIO_HOST = 126
36};
37
38
39static uint32_t type_prio(enum ice_cand_type type)
40{
41 switch (type) {
42
43 case ICE_CAND_TYPE_HOST: return CAND_PRIO_HOST;
44 case ICE_CAND_TYPE_SRFLX: return CAND_PRIO_SRFLX;
45 case ICE_CAND_TYPE_PRFLX: return CAND_PRIO_PRFLX;
46 case ICE_CAND_TYPE_RELAY: return CAND_PRIO_RELAY;
47 default: return 0;
48 }
49}
50
51
52uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
53 unsigned compid)
54{
55 return type_prio(type)<<24 | (uint32_t)local<<8 | (256 - compid);
56}
57
58
59/*
60 * g = controlling agent
61 * d = controlled agent
62
63 pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
64
65 */
66uint64_t ice_calc_pair_prio(uint32_t g, uint32_t d)
67{
68 const uint64_t m = min(g, d);
69 const uint64_t x = max(g, d);
70
71 return (m<<32) + 2*x + (g>d?1:0);
72}
73
74
75void ice_switch_local_role(struct icem *icem)
76{
77 enum ice_role new_role;
78
79 if (ICE_ROLE_CONTROLLING == icem->lrole)
80 new_role = ICE_ROLE_CONTROLLED;
81 else
82 new_role = ICE_ROLE_CONTROLLING;
83
84 DEBUG_NOTICE("Switch local role from %s to %s\n",
85 ice_role2name(icem->lrole), ice_role2name(new_role));
86
87 icem->lrole = new_role;
88
89#if 0
90 /* recompute pair priorities for all media streams */
91 for (le = icem->le.list->head; le; le = le->next) {
92 icem = le->data;
93 icem_candpair_prio_order(&icem->checkl);
94 }
95#endif
96}
97
98
99/**
100 * Remove duplicate elements from list, preserving order
101 *
102 * @param list Linked list
103 * @param uh Unique handler (return object to remove)
104 *
105 * @return Number of elements removed
106 *
107 * @note: O (n ^ 2)
108 */
109uint32_t ice_list_unique(struct list *list, list_unique_h *uh)
110{
111 struct le *le1 = list_head(list);
112 uint32_t n = 0;
113
114 while (le1 && le1 != list->tail) {
115
116 struct le *le2 = le1->next;
117 void *data = NULL;
118
119 while (le2) {
120
121 data = uh(le1, le2);
122
123 le2 = le2->next;
124
125 if (!data)
126 continue;
127
128 if (le1->data == data)
129 break;
130 else {
131 data = mem_deref(data);
132 ++n;
133 }
134 }
135
136 le1 = le1->next;
137
138 if (data) {
139 mem_deref(data);
140 ++n;
141 }
142 }
143
144 return n;
145}