1 /** 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 31 enum { 32 CAND_PRIO_RELAY = 0, 33 CAND_PRIO_SRFLX = 100, 34 CAND_PRIO_PRFLX = 110, 35 CAND_PRIO_HOST = 126 36 }; 37 38 39 static 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 52 uint32_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 */ 66 uint64_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 75 void 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 */ 109 uint32_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 } 146