Changeset 1989
- Timestamp:
- Jun 6, 2008 2:50:13 PM (16 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/transport_ice.h
r1735 r1989 49 49 * 50 50 * @param tp PJMEDIA ICE transport. 51 * @param status ICE negotiation result, PJ_SUCCESS on success. 51 * @param op The operation 52 * @param status Operation status. 52 53 */ 53 54 void (*on_ice_complete)(pjmedia_transport *tp, 55 pj_ice_strans_op op, 54 56 pj_status_t status); 55 57 … … 63 65 * for logging purposes. 64 66 * @param comp_cnt Number of components to be created. 65 * @param stun_cfg Pointer to STUNconfiguration settings.67 * @param cfg Pointer to configuration settings. 66 68 * @param cb Optional callbacks. 67 69 * @param p_tp Pointer to receive the media transport instance. … … 72 74 const char *name, 73 75 unsigned comp_cnt, 74 pj_stun_config *stun_cfg,76 const pj_ice_strans_cfg *cfg, 75 77 const pjmedia_ice_cb *cb, 76 78 pjmedia_transport **p_tp); 77 78 79 /**80 * Start the initialization process of this media transport. This function81 * will gather the transport addresses to be registered to ICE session as82 * candidates. If STUN is configured, this will start the STUN Binding or83 * Allocate request to get the STUN server reflexive or relayed address.84 * This function will return immediately, and application should poll the85 * STUN completion status by calling #pjmedia_ice_get_init_status().86 *87 * @param tp The media transport.88 * @param options Options, see pj_ice_strans_option in PJNATH89 * documentation.90 * @param start_addr Local address where socket will be bound to. This91 * address will be used as follows:92 * - if the value is NULL, then socket will be bound93 * to any available port.94 * - if the value is not NULL, then if the port number95 * is not zero, it will used as the starting port96 * where the socket will be bound to. If bind() to97 * this port fails, this function will try to bind98 * to port+2, repeatedly until it succeeded.99 * If application doesn't want this function to100 * retry binding the socket to other port, it can101 * specify PJ_ICE_ST_OPT_NO_PORT_RETRY option.102 * - if the value is not NULL, then if the address103 * is not INADDR_ANY, this function will bind the104 * socket to this particular interface only, and105 * no other host candidates will be added for this106 * socket.107 * @param stun_srv Address of the STUN server, or NULL if STUN server108 * reflexive mapping is not to be used.109 * @param turn_srv Address of the TURN server, or NULL if TURN relay110 * is not to be used.111 *112 * @return PJ_SUCCESS when the initialization process has started113 * successfully, or the appropriate error code.114 */115 PJ_DECL(pj_status_t) pjmedia_ice_start_init(pjmedia_transport *tp,116 unsigned options,117 const pj_sockaddr_in *start_addr,118 const pj_sockaddr_in *stun_srv,119 const pj_sockaddr_in *turn_srv);120 121 /**122 * Poll the initialization status of this media transport.123 *124 * @param tp The media transport.125 *126 * @return PJ_SUCCESS if all candidates have been resolved127 * successfully, PJ_EPENDING if transport resolution128 * is still in progress, or other status on failure.129 */130 PJ_DECL(pj_status_t) pjmedia_ice_get_init_status(pjmedia_transport *tp);131 132 133 /**134 * Get the ICE stream transport component for the specified component ID.135 *136 * @param tp The media transport.137 * @param comp_id The component ID.138 * @param comp The structure which will be filled with the139 * component.140 *141 * @return PJ_SUCCESS or the appropriate error code.142 */143 PJ_DECL(pj_status_t) pjmedia_ice_get_comp(pjmedia_transport *tp,144 unsigned comp_id,145 pj_ice_strans_comp *comp);146 147 /**148 * Initialize the ICE session.149 *150 * @param tp The media transport.151 * @param role ICE role.152 * @param local_ufrag Optional local username fragment.153 * @param local_passwd Optional local password.154 *155 * @return PJ_SUCCESS, or the appropriate error code.156 157 */158 PJ_DECL(pj_status_t) pjmedia_ice_init_ice(pjmedia_transport *tp,159 pj_ice_sess_role role,160 const pj_str_t *local_ufrag,161 const pj_str_t *local_passwd);162 163 79 164 80 PJ_END_DECL -
pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c
r1944 r1989 30 30 { 31 31 pjmedia_transport base; 32 pj_pool_t *pool; 33 int af; 34 unsigned comp_cnt; 32 35 pj_ice_strans *ice_st; 33 36 pjmedia_ice_cb cb; 34 37 unsigned media_option; 35 38 36 pj_time_val start_ice;37 38 39 void *stream; 39 40 pj_sockaddr_in remote_rtp; … … 85 86 unsigned options, 86 87 pjmedia_sdp_session *sdp_local, 87 const pjmedia_sdp_session * sdp_remote,88 const pjmedia_sdp_session *rem_sdp, 88 89 unsigned media_index); 89 90 static pj_status_t transport_media_start (pjmedia_transport *tp, 90 91 pj_pool_t *pool, 91 92 pjmedia_sdp_session *sdp_local, 92 const pjmedia_sdp_session * sdp_remote,93 const pjmedia_sdp_session *rem_sdp, 93 94 unsigned media_index); 94 95 static pj_status_t transport_media_stop(pjmedia_transport *tp); … … 101 102 * And these are ICE callbacks. 102 103 */ 103 static void ice_on_rx_data(pj_ice_strans *ice_st, unsigned comp_id, 104 static void ice_on_rx_data(pj_ice_strans *ice_st, 105 unsigned comp_id, 104 106 void *pkt, pj_size_t size, 105 107 const pj_sockaddr_t *src_addr, 106 108 unsigned src_addr_len); 107 109 static void ice_on_ice_complete(pj_ice_strans *ice_st, 110 pj_ice_strans_op op, 108 111 pj_status_t status); 109 112 … … 135 138 const char *name, 136 139 unsigned comp_cnt, 137 pj_stun_config *stun_cfg,140 const pj_ice_strans_cfg *cfg, 138 141 const pjmedia_ice_cb *cb, 139 142 pjmedia_transport **p_tp) 140 143 { 141 pj_ ice_strans *ice_st;144 pj_pool_t *pool; 142 145 pj_ice_strans_cb ice_st_cb; 143 146 struct transport_ice *tp_ice; 144 147 pj_status_t status; 145 148 146 PJ_UNUSED_ARG(endpt); 149 PJ_ASSERT_RETURN(endpt && comp_cnt && cfg && p_tp, PJ_EINVAL); 150 151 /* Create transport instance */ 152 pool = pjmedia_endpt_create_pool(endpt, name, 512, 512); 153 tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice); 154 tp_ice->pool = pool; 155 tp_ice->af = cfg->af; 156 tp_ice->comp_cnt = comp_cnt; 157 pj_ansi_strcpy(tp_ice->base.name, pool->obj_name); 158 tp_ice->base.op = &transport_ice_op; 159 tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE; 160 161 if (cb) 162 pj_memcpy(&tp_ice->cb, cb, sizeof(pjmedia_ice_cb)); 163 164 /* Assign return value first because ICE might call callback 165 * in create() 166 */ 167 *p_tp = &tp_ice->base; 147 168 148 169 /* Configure ICE callbacks */ … … 152 173 153 174 /* Create ICE */ 154 status = pj_ice_strans_create(stun_cfg, name, comp_cnt, NULL, 155 &ice_st_cb, &ice_st); 156 if (status != PJ_SUCCESS) 175 status = pj_ice_strans_create(name, cfg, comp_cnt, tp_ice, 176 &ice_st_cb, &tp_ice->ice_st); 177 if (status != PJ_SUCCESS) { 178 pj_pool_release(pool); 179 *p_tp = NULL; 157 180 return status; 158 159 160 /* Create transport instance and attach to ICE */ 161 tp_ice = PJ_POOL_ZALLOC_T(ice_st->pool, struct transport_ice); 162 tp_ice->ice_st = ice_st; 163 pj_ansi_strcpy(tp_ice->base.name, ice_st->obj_name); 164 tp_ice->base.op = &transport_ice_op; 165 tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE; 166 167 if (cb) 168 pj_memcpy(&tp_ice->cb, cb, sizeof(pjmedia_ice_cb)); 169 170 ice_st->user_data = (void*)tp_ice; 181 } 171 182 172 183 /* Done */ 173 if (p_tp)174 *p_tp = &tp_ice->base;175 176 184 return PJ_SUCCESS; 177 185 } 178 186 179 180 /* 181 * Start media transport initialization. 182 */ 183 PJ_DEF(pj_status_t) pjmedia_ice_start_init( pjmedia_transport *tp, 184 unsigned options, 185 const pj_sockaddr_in *start_addr, 186 const pj_sockaddr_in *stun_srv, 187 const pj_sockaddr_in *turn_srv) 188 { 189 struct transport_ice *tp_ice = (struct transport_ice*)tp; 190 pj_status_t status; 191 192 status = pj_ice_strans_set_stun_srv(tp_ice->ice_st, stun_srv, turn_srv); 193 if (status != PJ_SUCCESS) 194 return status; 195 196 status = pj_ice_strans_create_comp(tp_ice->ice_st, 1, options, start_addr); 197 if (status != PJ_SUCCESS) 198 return status; 199 200 if (tp_ice->ice_st->comp_cnt > 1) { 201 pj_sockaddr_in addr; 202 pj_uint16_t port; 203 204 pj_memcpy(&addr, &tp_ice->ice_st->comp[0]->local_addr.ipv4, 205 sizeof(pj_sockaddr_in)); 206 if (start_addr) 207 addr.sin_addr.s_addr = start_addr->sin_addr.s_addr; 208 else 209 addr.sin_addr.s_addr = 0; 210 211 port = pj_ntohs(addr.sin_port); 212 ++port; 213 addr.sin_port = pj_htons(port); 214 status = pj_ice_strans_create_comp(tp_ice->ice_st, 2, options, &addr); 215 if (status != PJ_SUCCESS) 216 return status; 217 } 218 return status; 219 } 220 221 222 /* 223 * Get the status of media transport initialization. 224 */ 225 PJ_DEF(pj_status_t) pjmedia_ice_get_init_status(pjmedia_transport *tp) 226 { 227 struct transport_ice *tp_ice = (struct transport_ice*)tp; 228 return pj_ice_strans_get_comps_status(tp_ice->ice_st); 229 } 230 231 232 /* 233 * Get the component for the specified component ID. 234 */ 235 PJ_DEF(pj_status_t) pjmedia_ice_get_comp( pjmedia_transport *tp, 236 unsigned comp_id, 237 pj_ice_strans_comp *comp) 238 { 239 struct transport_ice *tp_ice = (struct transport_ice*)tp; 240 PJ_ASSERT_RETURN(tp && comp_id && comp_id <= tp_ice->ice_st->comp_cnt && 241 comp, PJ_EINVAL); 242 243 pj_memcpy(comp, tp_ice->ice_st->comp[comp_id-1], 244 sizeof(pj_ice_strans_comp)); 245 return PJ_SUCCESS; 246 } 247 248 249 /* 250 * Create ICE! This happens when: 251 * - UAC is ready to send offer 252 * - UAS have just received an offer. 253 */ 254 PJ_DEF(pj_status_t) pjmedia_ice_init_ice(pjmedia_transport *tp, 255 pj_ice_sess_role role, 256 const pj_str_t *local_ufrag, 257 const pj_str_t *local_passwd) 258 { 259 struct transport_ice *tp_ice = (struct transport_ice*)tp; 260 return pj_ice_strans_init_ice(tp_ice->ice_st, role, local_ufrag, 261 local_passwd); 262 } 263 187 /* Create SDP candidate attribute */ 188 static int print_sdp_cand_attr(char *buffer, int max_len, 189 const pj_ice_sess_cand *cand) 190 { 191 char ipaddr[PJ_INET6_ADDRSTRLEN+2]; 192 int len, len2; 193 194 len = pj_ansi_snprintf( buffer, max_len, 195 "%.*s %u UDP %u %s %u typ ", 196 (int)cand->foundation.slen, 197 cand->foundation.ptr, 198 (unsigned)cand->comp_id, 199 cand->prio, 200 pj_sockaddr_print(&cand->addr, ipaddr, 201 sizeof(ipaddr), 0), 202 (unsigned)pj_sockaddr_get_port(&cand->addr)); 203 if (len < 1 || len >= max_len) 204 return -1; 205 206 switch (cand->type) { 207 case PJ_ICE_CAND_TYPE_HOST: 208 len2 = pj_ansi_snprintf(buffer+len, max_len-len, "host"); 209 break; 210 case PJ_ICE_CAND_TYPE_SRFLX: 211 case PJ_ICE_CAND_TYPE_RELAYED: 212 case PJ_ICE_CAND_TYPE_PRFLX: 213 len2 = pj_ansi_snprintf(buffer+len, max_len-len, 214 "srflx raddr %s rport %d", 215 pj_sockaddr_print(&cand->rel_addr, ipaddr, 216 sizeof(ipaddr), 0), 217 (int)pj_sockaddr_get_port(&cand->rel_addr)); 218 break; 219 default: 220 pj_assert(!"Invalid candidate type"); 221 len2 = -1; 222 break; 223 } 224 if (len2 < 1 || len2 >= max_len) 225 return -1; 226 227 return len+len2; 228 } 264 229 265 230 /* … … 268 233 */ 269 234 static pj_status_t transport_media_create(pjmedia_transport *tp, 270 pj_pool_t *pool,271 272 273 const pjmedia_sdp_session *sdp_remote,274 235 pj_pool_t *pool, 236 unsigned options, 237 pjmedia_sdp_session *sdp_local, 238 const pjmedia_sdp_session *rem_sdp, 239 unsigned media_index) 275 240 { 276 241 struct transport_ice *tp_ice = (struct transport_ice*)tp; 277 pj_ice_sess_role ice_role; 278 enum { MAXLEN = 256 }; 279 char *buffer; 280 pjmedia_sdp_attr *attr; 281 unsigned i, cand_cnt; 242 pj_bool_t init_ice; 243 unsigned i; 282 244 pj_status_t status; 283 245 … … 285 247 286 248 /* Validate media transport */ 287 /* Bynow, this transport only support RTP/AVP transport */249 /* For now, this transport only support RTP/AVP transport */ 288 250 if ((tp_ice->media_option & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) { 289 251 pjmedia_sdp_media *m_rem, *m_loc; 290 252 291 m_rem = sdp_remote? sdp_remote->media[media_index] : NULL;253 m_rem = rem_sdp? rem_sdp->media[media_index] : NULL; 292 254 m_loc = sdp_local->media[media_index]; 293 255 … … 300 262 } 301 263 264 /* If we are UAS, check that the incoming SDP contains support for ICE. */ 265 if (rem_sdp) { 266 const pjmedia_sdp_media *rem_m; 267 268 rem_m = rem_sdp->media[media_index]; 269 270 init_ice = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 271 "ice-ufrag", NULL) != NULL; 272 if (init_ice == PJ_FALSE) { 273 init_ice = pjmedia_sdp_attr_find2(rem_sdp->attr_count, 274 rem_sdp->attr, 275 "ice-ufrag", NULL) != NULL; 276 } 277 278 if (init_ice) { 279 init_ice = pjmedia_sdp_attr_find2(rem_m->attr_count, rem_m->attr, 280 "candidate", NULL) != NULL; 281 } 282 } else { 283 init_ice = PJ_TRUE; 284 } 285 302 286 /* Init ICE */ 303 ice_role = (sdp_remote==NULL ? PJ_ICE_SESS_ROLE_CONTROLLING : 304 PJ_ICE_SESS_ROLE_CONTROLLED); 305 306 status = pjmedia_ice_init_ice(tp, ice_role, NULL, NULL); 307 if (status != PJ_SUCCESS) 308 return status; 309 310 311 buffer = (char*) pj_pool_alloc(pool, MAXLEN); 312 313 /* Create ice-ufrag attribute */ 314 attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", 315 &tp_ice->ice_st->ice->rx_ufrag); 316 sdp_local->attr[sdp_local->attr_count++] = attr; 317 318 /* Create ice-pwd attribute */ 319 attr = pjmedia_sdp_attr_create(pool, "ice-pwd", 320 &tp_ice->ice_st->ice->rx_pass); 321 sdp_local->attr[sdp_local->attr_count++] = attr; 322 323 /* Add all candidates (to media level) */ 324 cand_cnt = tp_ice->ice_st->ice->lcand_cnt; 325 for (i=0; i<cand_cnt; ++i) { 326 pj_ice_sess_cand *cand; 327 pjmedia_sdp_media *m; 328 pj_str_t value; 329 int len; 330 331 cand = &tp_ice->ice_st->ice->lcand[i]; 332 333 len = pj_ansi_snprintf( buffer, MAXLEN, 334 "%.*s %d UDP %u %s %d typ ", 335 (int)cand->foundation.slen, 336 cand->foundation.ptr, 337 cand->comp_id, 338 cand->prio, 339 pj_inet_ntoa(cand->addr.ipv4.sin_addr), 340 (int)pj_ntohs(cand->addr.ipv4.sin_port)); 341 if (len < 1 || len >= MAXLEN) 342 return PJ_ENAMETOOLONG; 343 344 switch (cand->type) { 345 case PJ_ICE_CAND_TYPE_HOST: 346 len = pj_ansi_snprintf(buffer+len, MAXLEN-len, 347 "host"); 348 break; 349 case PJ_ICE_CAND_TYPE_SRFLX: 350 len = pj_ansi_snprintf(buffer+len, MAXLEN-len, 351 "srflx raddr %s rport %d", 352 pj_inet_ntoa(cand->base_addr.ipv4.sin_addr), 353 (int)pj_ntohs(cand->base_addr.ipv4.sin_port)); 354 break; 355 case PJ_ICE_CAND_TYPE_RELAYED: 356 PJ_TODO(RELATED_ADDR_FOR_RELAYED_ADDR); 357 len = pj_ansi_snprintf(buffer+len, MAXLEN-len, 358 "srflx raddr %s rport %d", 359 pj_inet_ntoa(cand->base_addr.ipv4.sin_addr), 360 (int)pj_ntohs(cand->base_addr.ipv4.sin_port)); 361 break; 362 case PJ_ICE_CAND_TYPE_PRFLX: 363 len = pj_ansi_snprintf(buffer+len, MAXLEN-len, 364 "prflx raddr %s rport %d", 365 pj_inet_ntoa(cand->base_addr.ipv4.sin_addr), 366 (int)pj_ntohs(cand->base_addr.ipv4.sin_port)); 367 break; 368 default: 369 pj_assert(!"Invalid candidate type"); 370 break; 371 } 372 if (len < 1 || len >= MAXLEN) 373 return PJ_ENAMETOOLONG; 374 375 value = pj_str(buffer); 376 attr = pjmedia_sdp_attr_create(pool, "candidate", &value); 377 m = sdp_local->media[media_index]; 378 m->attr[m->attr_count++] = attr; 287 if (init_ice) { 288 pj_ice_sess_role ice_role; 289 enum { MAXLEN = 256 }; 290 pj_str_t ufrag, pass; 291 char *buffer; 292 pjmedia_sdp_attr *attr; 293 unsigned comp; 294 295 ice_role = (rem_sdp==NULL ? PJ_ICE_SESS_ROLE_CONTROLLING : 296 PJ_ICE_SESS_ROLE_CONTROLLED); 297 298 ufrag.ptr = (char*) pj_pool_alloc(pool, PJ_ICE_UFRAG_LEN); 299 pj_create_random_string(ufrag.ptr, PJ_ICE_UFRAG_LEN); 300 ufrag.slen = PJ_ICE_UFRAG_LEN; 301 302 pass.ptr = (char*) pj_pool_alloc(pool, PJ_ICE_UFRAG_LEN); 303 pj_create_random_string(pass.ptr, PJ_ICE_UFRAG_LEN); 304 pass.slen = PJ_ICE_UFRAG_LEN; 305 306 status = pj_ice_strans_init_ice(tp_ice->ice_st, ice_role, 307 &ufrag, &pass); 308 if (status != PJ_SUCCESS) 309 return status; 310 311 /* Create ice-ufrag attribute */ 312 attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", &ufrag); 313 sdp_local->attr[sdp_local->attr_count++] = attr; 314 315 /* Create ice-pwd attribute */ 316 attr = pjmedia_sdp_attr_create(pool, "ice-pwd", &pass); 317 sdp_local->attr[sdp_local->attr_count++] = attr; 318 319 /* Encode all candidates to SDP media */ 320 321 buffer = (char*) pj_pool_alloc(pool, MAXLEN); 322 323 for (comp=0; comp < tp_ice->comp_cnt; ++comp) { 324 unsigned cand_cnt; 325 pj_ice_sess_cand cand[PJ_ICE_ST_MAX_CAND]; 326 327 cand_cnt = PJ_ARRAY_SIZE(cand); 328 status = pj_ice_strans_enum_cands(tp_ice->ice_st, comp+1, 329 &cand_cnt, cand); 330 if (status != PJ_SUCCESS) 331 return status; 332 333 for (i=0; i<cand_cnt; ++i) { 334 pjmedia_sdp_media *m; 335 pj_str_t value; 336 337 value.slen = print_sdp_cand_attr(buffer, MAXLEN, &cand[i]); 338 if (value.slen < 0) { 339 pj_assert(!"Not enough buffer to print candidate"); 340 return PJ_EBUG; 341 } 342 343 value.ptr = buffer; 344 attr = pjmedia_sdp_attr_create(pool, "candidate", &value); 345 m = sdp_local->media[media_index]; 346 m->attr[m->attr_count++] = attr; 347 } 348 } 379 349 } 380 350 381 351 /* Done */ 382 352 return PJ_SUCCESS; 383 384 353 } 385 354 … … 412 381 goto on_return; 413 382 } 414 cand->comp_id = atoi(token);383 cand->comp_id = (pj_uint8_t) atoi(token); 415 384 416 385 /* Transport */ … … 501 470 static void set_no_ice(struct transport_ice *tp_ice, const char *reason) 502 471 { 503 PJ_LOG(4,(tp_ice-> ice_st->obj_name,472 PJ_LOG(4,(tp_ice->base.name, 504 473 "Disabling local ICE, reason=%s", reason)); 505 474 transport_media_stop(&tp_ice->base); … … 513 482 pj_pool_t *pool, 514 483 pjmedia_sdp_session *sdp_local, 515 const pjmedia_sdp_session * sdp_remote,484 const pjmedia_sdp_session *rem_sdp, 516 485 unsigned media_index) 517 486 { … … 529 498 pj_status_t status; 530 499 531 PJ_ASSERT_RETURN(tp && pool && sdp_remote, PJ_EINVAL);532 PJ_ASSERT_RETURN(media_index < sdp_remote->media_count, PJ_EINVAL);533 534 sdp_med = sdp_remote->media[media_index];500 PJ_ASSERT_RETURN(tp && pool && rem_sdp, PJ_EINVAL); 501 PJ_ASSERT_RETURN(media_index < rem_sdp->media_count, PJ_EINVAL); 502 503 sdp_med = rem_sdp->media[media_index]; 535 504 536 505 /* Validate media transport */ … … 539 508 pjmedia_sdp_media *m_rem, *m_loc; 540 509 541 m_rem = sdp_remote->media[media_index];510 m_rem = rem_sdp->media[media_index]; 542 511 m_loc = sdp_local->media[media_index]; 543 512 … … 556 525 conn = sdp_med->conn; 557 526 if (conn == NULL) 558 conn = sdp_remote->conn;527 conn = rem_sdp->conn; 559 528 560 529 if (conn == NULL) { … … 571 540 if (attr == NULL) { 572 541 /* Find ice-ufrag attribute in session descriptor */ 573 attr = pjmedia_sdp_attr_find2( sdp_remote->attr_count, sdp_remote->attr,542 attr = pjmedia_sdp_attr_find2(rem_sdp->attr_count, rem_sdp->attr, 574 543 "ice-ufrag", NULL); 575 544 if (attr == NULL) { … … 585 554 if (attr == NULL) { 586 555 /* Find ice-pwd attribute in session descriptor */ 587 attr = pjmedia_sdp_attr_find2( sdp_remote->attr_count, sdp_remote->attr,556 attr = pjmedia_sdp_attr_find2(rem_sdp->attr_count, rem_sdp->attr, 588 557 "ice-pwd", NULL); 589 558 if (attr == NULL) { … … 654 623 } 655 624 656 /* Mark start time */657 pj_gettimeofday(&tp_ice->start_ice);658 659 625 /* If our role was controlled but it turns out that remote is 660 626 * a lite implementation, change our role to controlling. 661 627 */ 662 628 if (remote_is_lite && 663 tp_ice->ice_st->ice->role== PJ_ICE_SESS_ROLE_CONTROLLED)629 pj_ice_strans_get_role(tp_ice->ice_st) == PJ_ICE_SESS_ROLE_CONTROLLED) 664 630 { 665 pj_ice_s ess_change_role(tp_ice->ice_st->ice,666 PJ_ICE_SESS_ROLE_CONTROLLING);631 pj_ice_strans_change_role(tp_ice->ice_st, 632 PJ_ICE_SESS_ROLE_CONTROLLING); 667 633 } 668 634 669 635 /* Start ICE */ 670 return pj_ice_strans_start_ice(tp_ice->ice_st, &uname, &pass, cand_cnt, cand); 636 return pj_ice_strans_start_ice(tp_ice->ice_st, &uname, &pass, 637 cand_cnt, cand); 671 638 } 672 639 … … 683 650 { 684 651 struct transport_ice *tp_ice = (struct transport_ice*)tp; 685 pj_ice_s trans *ice_st = tp_ice->ice_st;686 pj_ ice_strans_comp *comp;652 pj_ice_sess_cand cand; 653 pj_status_t status; 687 654 688 655 pj_bzero(&info->sock_info, sizeof(info->sock_info)); 689 656 info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET; 690 657 691 /* Retrieve address of default candidate for component 1 (RTP) */ 692 comp = ice_st->comp[0]; 693 pj_assert(comp->default_cand >= 0); 694 info->sock_info.rtp_sock = comp->sock; 695 pj_memcpy(&info->sock_info.rtp_addr_name, 696 &comp->cand_list[comp->default_cand].addr, 697 sizeof(pj_sockaddr_in)); 698 699 /* Retrieve address of default candidate for component 12(RTCP) */ 700 if (ice_st->comp_cnt > 1) { 701 comp = ice_st->comp[1]; 702 pj_assert(comp->default_cand >= 0); 703 info->sock_info.rtp_sock = comp->sock; 704 pj_memcpy(&info->sock_info.rtcp_addr_name, 705 &comp->cand_list[comp->default_cand].addr, 706 sizeof(pj_sockaddr_in)); 658 /* Get RTP default address */ 659 status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 1, &cand); 660 if (status != PJ_SUCCESS) 661 return status; 662 663 pj_sockaddr_cp(&info->sock_info.rtp_addr_name, &cand.addr); 664 665 /* Get RTCP default address */ 666 if (tp_ice->comp_cnt > 1) { 667 status = pj_ice_strans_get_def_cand(tp_ice->ice_st, 2, &cand); 668 if (status != PJ_SUCCESS) 669 return status; 670 671 pj_sockaddr_cp(&info->sock_info.rtcp_addr_name, &cand.addr); 707 672 } 708 673 … … 760 725 if (tp_ice->tx_drop_pct) { 761 726 if ((pj_rand() % 100) <= (int)tp_ice->tx_drop_pct) { 762 PJ_LOG(5,(tp_ice-> ice_st->obj_name,727 PJ_LOG(5,(tp_ice->base.name, 763 728 "TX RTP packet dropped because of pkt lost " 764 729 "simulation")); … … 787 752 { 788 753 struct transport_ice *tp_ice = (struct transport_ice*)tp; 789 if (tp_ice-> ice_st->comp_cnt > 1) {754 if (tp_ice->comp_cnt > 1) { 790 755 if (addr == NULL) { 791 756 addr = &tp_ice->remote_rtcp; … … 805 770 unsigned src_addr_len) 806 771 { 807 struct transport_ice *tp_ice = (struct transport_ice*) ice_st->user_data; 772 struct transport_ice *tp_ice; 773 774 tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st); 808 775 809 776 if (comp_id==1 && tp_ice->rtp_cb) { … … 812 779 if (tp_ice->rx_drop_pct) { 813 780 if ((pj_rand() % 100) <= (int)tp_ice->rx_drop_pct) { 814 PJ_LOG(5,( ice_st->obj_name,781 PJ_LOG(5,(tp_ice->base.name, 815 782 "RX RTP packet dropped because of pkt lost " 816 783 "simulation")); … … 826 793 PJ_UNUSED_ARG(src_addr); 827 794 PJ_UNUSED_ARG(src_addr_len); 828 829 PJ_TODO(SWITCH_SOURCE_ADDRESS);830 795 } 831 796 832 797 833 798 static void ice_on_ice_complete(pj_ice_strans *ice_st, 799 pj_ice_strans_op op, 834 800 pj_status_t result) 835 801 { 836 struct transport_ice *tp_ice = (struct transport_ice*) ice_st->user_data; 837 pj_time_val end_ice; 838 pj_ice_sess_cand *lcand, *rcand; 839 pj_ice_sess_check *check; 840 char src_addr[32]; 841 char dst_addr[32]; 842 843 pj_gettimeofday(&end_ice); 844 PJ_TIME_VAL_SUB(end_ice, tp_ice->start_ice); 845 846 if (result != PJ_SUCCESS) { 847 char errmsg[PJ_ERR_MSG_SIZE]; 848 pj_strerror(result, errmsg, sizeof(errmsg)); 849 PJ_LOG(1,(ice_st->obj_name, 850 "ICE negotiation failed after %d:%03ds: %s", 851 (int)end_ice.sec, (int)end_ice.msec, 852 errmsg)); 853 } else { 854 check = &ice_st->ice->valid_list.checks[0]; 855 856 lcand = check->lcand; 857 rcand = check->rcand; 858 859 pj_ansi_strcpy(src_addr, pj_inet_ntoa(lcand->addr.ipv4.sin_addr)); 860 pj_ansi_strcpy(dst_addr, pj_inet_ntoa(rcand->addr.ipv4.sin_addr)); 861 862 PJ_LOG(4,(ice_st->obj_name, 863 "ICE negotiation completed in %d.%03ds. Sending from " 864 "%s:%d to %s:%d", 865 (int)end_ice.sec, (int)end_ice.msec, 866 src_addr, pj_ntohs(lcand->addr.ipv4.sin_port), 867 dst_addr, pj_ntohs(rcand->addr.ipv4.sin_port))); 868 } 802 struct transport_ice *tp_ice; 803 804 tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st); 869 805 870 806 /* Notify application */ 871 807 if (tp_ice->cb.on_ice_complete) 872 (*tp_ice->cb.on_ice_complete)(&tp_ice->base, result);808 (*tp_ice->cb.on_ice_complete)(&tp_ice->base, op, result); 873 809 } 874 810 … … 902 838 if (tp_ice->ice_st) { 903 839 pj_ice_strans_destroy(tp_ice->ice_st); 904 /*Must not touch tp_ice after ice_st is destroyed! 905 (it has the pool) 906 tp_ice->ice_st = NULL; 907 */ 840 tp_ice->ice_st = NULL; 841 } 842 843 if (tp_ice->pool) { 844 pj_pool_t *pool = tp_ice->pool; 845 tp_ice->pool = NULL; 846 pj_pool_release(pool); 908 847 } 909 848
Note: See TracChangeset
for help on using the changeset viewer.