- Timestamp:
- May 17, 2009 5:57:19 PM (16 years ago)
- Location:
- pjproject/branches/projects/sipit24
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/sipit24/pjnath/include/pjnath/config.h
r2642 r2705 325 325 326 326 /** 327 * For a controlled agent, specify how long it wants to wait (in milliseconds) 328 * for the controlling agent to complete sending connectivity check with 329 * nominated flag set to true for all components after the controlled agent 330 * has found that all connectivity checks in its checklist have been completed 331 * and there is at least one successful (but not nominated) check for every 332 * component. 333 * 334 * When selecting the value, bear in mind that the connectivity check from 335 * controlling agent may be delayed because of delay in receiving SDP answer 336 * from the controlled agent. 337 * 338 * Application may set this value to -1 to disable this timer. 339 * 340 * Default: 10000 (milliseconds) 341 */ 342 #ifndef ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT 343 # define ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT 10000 344 #endif 345 346 347 /** 348 * For controlling agent if it uses regular nomination, specify the delay to 349 * perform nominated check (connectivity check with USE-CANDIDATE attribute) 350 * after all components have a valid pair. 351 * 352 * Default: 4*PJ_STUN_RTO_VALUE (milliseconds) 353 */ 354 #ifndef PJ_ICE_NOMINATED_CHECK_DELAY 355 # define PJ_ICE_NOMINATED_CHECK_DELAY (4*PJ_STUN_RTO_VALUE) 356 #endif 357 358 359 /** 327 360 * Minimum interval value to be used for sending STUN keep-alive on the ICE 328 361 * stream transport, in seconds. This minimum interval, plus a random value -
pjproject/branches/projects/sipit24/pjnath/include/pjnath/errno.h
r2642 r2705 197 197 */ 198 198 #define PJNATH_EICENOHOSTCAND (PJNATH_ERRNO_START+92) /* 370092 */ 199 199 /** 200 * @hideinitializer 201 * Controlled agent timed-out in waiting for the controlling agent to 202 * send nominated check after all connectivity checks have completed. 203 */ 204 #define PJNATH_EICENOMTIMEOUT (PJNATH_ERRNO_START+93) /* 370093 */ 200 205 201 206 /************************************************************ -
pjproject/branches/projects/sipit24/pjnath/include/pjnath/ice_session.h
r2642 r2705 177 177 { 178 178 /** 179 * The pointer to ICE check which was nominated for this component.180 * The value will be NULL if a nominated check has not been found181 * for this component.179 * Pointer to ICE check with highest priority which connectivity check 180 * has been successful. The value will be NULL if a no successful check 181 * has not been found for this component. 182 182 */ 183 183 pj_ice_sess_check *valid_check; 184 185 /** 186 * Pointer to ICE check with highest priority which connectivity check 187 * has been successful and it has been nominated. The value may be NULL 188 * if there is no such check yet. 189 */ 190 pj_ice_sess_check *nominated_check; 184 191 185 192 /** … … 554 561 555 562 /** 563 * This structure describes various ICE session options. Application 564 * configure the ICE session with these options by calling 565 * #pj_ice_sess_set_options(). 566 */ 567 typedef struct pj_ice_sess_options 568 { 569 /** 570 * Specify whether to use aggressive nomination. 571 */ 572 pj_bool_t aggressive; 573 574 /** 575 * For controlling agent if it uses regular nomination, specify the delay 576 * to perform nominated check (connectivity check with USE-CANDIDATE 577 * attribute) after all components have a valid pair. 578 * 579 * Default value is PJ_ICE_NOMINATED_CHECK_DELAY. 580 */ 581 unsigned nominated_check_delay; 582 583 /** 584 * For a controlled agent, specify how long it wants to wait (in 585 * milliseconds) for the controlling agent to complete sending 586 * connectivity check with nominated flag set to true for all components 587 * after the controlled agent has found that all connectivity checks in 588 * its checklist have been completed and there is at least one successful 589 * (but not nominated) check for every component. 590 * 591 * Default value for this option is 592 * ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT. Specify -1 to disable 593 * this timer. 594 */ 595 int controlled_agent_want_nom_timeout; 596 597 } pj_ice_sess_options; 598 599 600 /** 556 601 * This structure describes the ICE session. For this version of PJNATH, 557 602 * an ICE session corresponds to a single media stream (unlike the ICE … … 570 615 pj_mutex_t *mutex; /**< Mutex. */ 571 616 pj_ice_sess_role role; /**< ICE role. */ 617 pj_ice_sess_options opt; /**< Options */ 572 618 pj_timestamp tie_breaker; /**< Tie breaker value */ 573 619 pj_uint8_t *prefs; /**< Type preference. */ 620 pj_bool_t is_nominating; /**< Nominating stage */ 574 621 pj_bool_t is_complete; /**< Complete? */ 575 622 pj_status_t ice_status; /**< Error status. */ 576 pj_timer_entry completion_timer; /**< To call callback.*/623 pj_timer_entry timer; /**< ICE timer. */ 577 624 pj_ice_sess_cb cb; /**< Callback. */ 578 625 … … 655 702 const pj_sockaddr *base_addr); 656 703 704 /** 705 * Initialize ICE session options with library default values. 706 * 707 * @param opt ICE session options. 708 */ 709 PJ_DECL(void) pj_ice_sess_options_default(pj_ice_sess_options *opt); 657 710 658 711 /** … … 690 743 691 744 /** 745 * Get the value of various options of the ICE session. 746 * 747 * @param ice The ICE session. 748 * @param opt The options to be initialized with the values 749 * from the ICE session. 750 * 751 * @return PJ_SUCCESS on success, or the appropriate error. 752 */ 753 PJ_DECL(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice, 754 pj_ice_sess_options *opt); 755 756 /** 757 * Specify various options for this ICE session. Application MUST only 758 * call this function after the ICE session has been created but before 759 * any connectivity check is started. 760 * 761 * Application should call #pj_ice_sess_get_options() to initialize the 762 * options with their default values. 763 * 764 * @param ice The ICE session. 765 * @param opt Options to be applied to the ICE session. 766 * 767 * @return PJ_SUCCESS on success, or the appropriate error. 768 */ 769 PJ_DECL(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice, 770 const pj_ice_sess_options *opt); 771 772 /** 692 773 * Destroy ICE session. This will cancel any connectivity checks currently 693 774 * running, if any, and any other events scheduled by this session, as well -
pjproject/branches/projects/sipit24/pjnath/include/pjnath/ice_strans.h
r2642 r2705 210 210 211 211 /** 212 * Disable host candidates. When this option is set, no213 * host candidates will be added.214 * 215 * Default: PJ_FALSE216 */ 217 pj_bool_t no_host_cands;212 * Maximum number of host candidates to be added. If the 213 * value is zero, no host candidates will be added. 214 * 215 * Default: 64 216 */ 217 unsigned max_host_cands; 218 218 219 219 /** … … 384 384 */ 385 385 PJ_DECL(void*) pj_ice_strans_get_user_data(pj_ice_strans *ice_st); 386 387 388 /** 389 * Get the value of various options of the ICE stream transport. 390 * 391 * @param ice_st The ICE stream transport. 392 * @param opt The options to be initialized with the values 393 * from the ICE stream transport. 394 * 395 * @return PJ_SUCCESS on success, or the appropriate error. 396 */ 397 PJ_DECL(pj_status_t) pj_ice_strans_get_options(pj_ice_strans *ice_st, 398 pj_ice_sess_options *opt); 399 400 /** 401 * Specify various options for this ICE stream transport. Application 402 * should call #pj_ice_strans_get_options() to initialize the options 403 * with their default values. 404 * 405 * @param ice_st The ICE stream transport. 406 * @param opt Options to be applied to this ICE stream transport. 407 * 408 * @return PJ_SUCCESS on success, or the appropriate error. 409 */ 410 PJ_DECL(pj_status_t) pj_ice_strans_set_options(pj_ice_strans *ice_st, 411 const pj_ice_sess_options *opt); 386 412 387 413 -
pjproject/branches/projects/sipit24/pjnath/src/pjnath-test/ice_test.c
r2394 r2705 142 142 143 143 if (ept->cfg.enable_host == 0) { 144 ice_cfg.stun. no_host_cands = PJ_TRUE;144 ice_cfg.stun.max_host_cands = 0; 145 145 } else { 146 ice_cfg.stun.no_host_cands = PJ_FALSE;146 //ice_cfg.stun.no_host_cands = PJ_FALSE; 147 147 ice_cfg.stun.loop_addr = PJ_TRUE; 148 148 } -
pjproject/branches/projects/sipit24/pjnath/src/pjnath/errno.c
r2580 r2705 68 68 PJ_BUILD_ERR( PJNATH_EICEINCANDSDP, "Invalid SDP \"candidate\" attribute"), 69 69 PJ_BUILD_ERR( PJNATH_EICENOHOSTCAND, "No host candidate associated with srflx"), 70 PJ_BUILD_ERR( PJNATH_EICENOMTIMEOUT, "Controlled agent timed out waiting for nomination"), 70 71 71 72 /* TURN related errors */ -
pjproject/branches/projects/sipit24/pjnath/src/pjnath/ice_session.c
r2419 r2705 67 67 }; 68 68 69 typedef enum timer_type 70 { 71 TIMER_NONE, /**< Timer not active */ 72 TIMER_COMPLETION_CALLBACK, /**< Call on_ice_complete() callback */ 73 TIMER_CONTROLLED_WAIT_NOM, /**< Controlled agent is waiting for 74 controlling agent to send connectivity 75 check with nominated flag after it has 76 valid check for every components. */ 77 TIMER_START_NOMINATED_CHECK,/**< Controlling agent start connectivity 78 checks with USE-CANDIDATE flag. */ 79 80 81 }; 82 69 83 /* Candidate type preference */ 70 84 static pj_uint8_t cand_type_prefs[4] = … … 119 133 120 134 /* Forward declarations */ 135 static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te); 136 static void on_ice_complete(pj_ice_sess *ice, pj_status_t status); 121 137 static void destroy_ice(pj_ice_sess *ice, 122 138 pj_status_t reason); 123 139 static pj_status_t start_periodic_check(pj_timer_heap_t *th, 124 140 pj_timer_entry *te); 141 static void start_nominated_check(pj_ice_sess *ice); 125 142 static void periodic_timer(pj_timer_heap_t *th, 126 143 pj_timer_entry *te); … … 297 314 298 315 316 /* Init options with default values */ 317 PJ_DEF(void) pj_ice_sess_options_default(pj_ice_sess_options *opt) 318 { 319 opt->aggressive = PJ_TRUE; 320 opt->nominated_check_delay = PJ_ICE_NOMINATED_CHECK_DELAY; 321 opt->controlled_agent_want_nom_timeout = 322 ICE_CONTROLLED_AGENT_WAIT_NOMINATION_TIMEOUT; 323 } 324 299 325 /* 300 326 * Create ICE session. … … 327 353 ice->tie_breaker.u32.lo = pj_rand(); 328 354 ice->prefs = cand_type_prefs; 355 pj_ice_sess_options_default(&ice->opt); 356 357 pj_timer_entry_init(&ice->timer, TIMER_NONE, (void*)ice, &on_timer); 329 358 330 359 pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name), … … 346 375 comp = &ice->comp[i]; 347 376 comp->valid_check = NULL; 377 comp->nominated_check = NULL; 348 378 349 379 status = init_comp(ice, i+1, comp); … … 390 420 391 421 /* 422 * Get the value of various options of the ICE session. 423 */ 424 PJ_DEF(pj_status_t) pj_ice_sess_get_options(pj_ice_sess *ice, 425 pj_ice_sess_options *opt) 426 { 427 PJ_ASSERT_RETURN(ice, PJ_EINVAL); 428 pj_memcpy(opt, &ice->opt, sizeof(*opt)); 429 return PJ_SUCCESS; 430 } 431 432 /* 433 * Specify various options for this ICE session. 434 */ 435 PJ_DEF(pj_status_t) pj_ice_sess_set_options(pj_ice_sess *ice, 436 const pj_ice_sess_options *opt) 437 { 438 PJ_ASSERT_RETURN(ice && opt, PJ_EINVAL); 439 pj_memcpy(&ice->opt, opt, sizeof(*opt)); 440 return PJ_SUCCESS; 441 } 442 443 444 /* 392 445 * Destroy 393 446 */ … … 407 460 } 408 461 409 if (ice-> completion_timer.id) {462 if (ice->timer.id) { 410 463 pj_timer_heap_cancel(ice->stun_cfg.timer_heap, 411 &ice-> completion_timer);412 ice-> completion_timer.id = PJ_FALSE;464 &ice->timer); 465 ice->timer.id = PJ_FALSE; 413 466 } 414 467 … … 1040 1093 } 1041 1094 1042 /* Timer callback to call on_ice_complete() callback */ 1043 static void on_completion_timer(pj_timer_heap_t *th, 1044 pj_timer_entry *te) 1095 /* Timer callback */ 1096 static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te) 1045 1097 { 1046 1098 pj_ice_sess *ice = (pj_ice_sess*) te->user_data; 1099 enum timer_time type = (enum timer_type)te->id; 1047 1100 1048 1101 PJ_UNUSED_ARG(th); 1049 1102 1050 te->id = PJ_FALSE; 1051 1052 if (ice->cb.on_ice_complete) 1053 (*ice->cb.on_ice_complete)(ice, ice->ice_status); 1103 te->id = TIMER_NONE; 1104 1105 switch (type) { 1106 case TIMER_CONTROLLED_WAIT_NOM: 1107 LOG4((ice->obj_name, 1108 "Controlled agent timed-out in waiting for the controlling " 1109 "agent to send nominated check. Setting state to fail now..")); 1110 on_ice_complete(ice, PJNATH_EICENOMTIMEOUT); 1111 break; 1112 case TIMER_COMPLETION_CALLBACK: 1113 if (ice->cb.on_ice_complete) 1114 (*ice->cb.on_ice_complete)(ice, ice->ice_status); 1115 break; 1116 case TIMER_START_NOMINATED_CHECK: 1117 start_nominated_check(ice); 1118 break; 1119 } 1054 1120 } 1055 1121 … … 1061 1127 ice->ice_status = status; 1062 1128 1129 if (ice->timer.id != TIMER_NONE) { 1130 pj_timer_heap_cancel(ice->stun_cfg.timer_heap, &ice->timer); 1131 ice->timer.id = TIMER_NONE; 1132 } 1133 1063 1134 /* Log message */ 1064 1135 LOG4((ice->obj_name, "ICE process complete, status=%s", … … 1072 1143 pj_time_val delay = {0, 0}; 1073 1144 1074 ice->completion_timer.cb = &on_completion_timer; 1075 ice->completion_timer.user_data = (void*) ice; 1076 ice->completion_timer.id = PJ_TRUE; 1077 1145 ice->timer.id = TIMER_COMPLETION_CALLBACK; 1078 1146 pj_timer_heap_schedule(ice->stun_cfg.timer_heap, 1079 &ice->completion_timer, 1080 &delay); 1147 &ice->timer, &delay); 1081 1148 } 1082 1149 } … … 1088 1155 pj_ice_sess_check *check) 1089 1156 { 1157 pj_ice_sess_comp *comp; 1090 1158 unsigned i; 1091 1159 1092 1160 pj_assert(check->state >= PJ_ICE_SESS_CHECK_STATE_SUCCEEDED); 1161 1162 comp = find_comp(ice, check->lcand->comp_id); 1093 1163 1094 1164 /* 7.1.2.2.2. Updating Pair States … … 1105 1175 */ 1106 1176 if (check->err_code==PJ_SUCCESS) { 1177 1107 1178 for (i=0; i<ice->clist.count; ++i) { 1108 1179 pj_ice_sess_check *c = &ice->clist.checks[i]; … … 1113 1184 } 1114 1185 } 1186 1187 /* Update valid check */ 1188 if (comp->valid_check == NULL) { 1189 comp->valid_check = check; 1190 } else { 1191 if (CMP_CHECK_PRIO(comp->valid_check, check) < 0) 1192 comp->valid_check = check; 1193 } 1194 1195 LOG5((ice->obj_name, "Check %d is successful%s", 1196 GET_CHECK_ID(&ice->clist, check), 1197 (check->nominated ? " and nominated" : ""))); 1198 1115 1199 } 1116 1200 … … 1137 1221 */ 1138 1222 if (check->err_code==PJ_SUCCESS && check->nominated) { 1139 pj_ice_sess_comp *comp;1140 1141 LOG5((ice->obj_name, "Check %d is successful and nominated",1142 GET_CHECK_ID(&ice->clist, check)));1143 1144 comp = find_comp(ice, check->lcand->comp_id);1145 1223 1146 1224 for (i=0; i<ice->clist.count; ++i) { … … 1182 1260 1183 1261 /* Update the nominated check for the component */ 1184 if (comp-> valid_check == NULL) {1185 comp-> valid_check = check;1262 if (comp->nominated_check == NULL) { 1263 comp->nominated_check = check; 1186 1264 } else { 1187 if (CMP_CHECK_PRIO(comp-> valid_check, check) < 0)1188 comp-> valid_check = check;1265 if (CMP_CHECK_PRIO(comp->nominated_check, check) < 0) 1266 comp->nominated_check = check; 1189 1267 } 1190 1268 } … … 1212 1290 */ 1213 1291 for (i=0; i<ice->comp_cnt; ++i) { 1214 if (ice->comp[i]. valid_check == NULL)1292 if (ice->comp[i].nominated_check == NULL) 1215 1293 break; 1216 1294 } … … 1259 1337 * If agent's role is controlled, check if all components have 1260 1338 * valid pair. If it does, this means the controlled agent has 1261 * finished the check list earlyand it's waiting for controlling1262 * agent to send a checkwith USE-CANDIDATE flag set.1339 * finished the check list and it's waiting for controlling 1340 * agent to send checks with USE-CANDIDATE flag set. 1263 1341 */ 1264 1342 if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLED) { 1265 unsigned comp_id; 1266 for (comp_id=1; comp_id <= ice->comp_cnt; ++comp_id) { 1267 unsigned j; 1268 for (j=0; j<ice->valid_list.count; ++j) { 1269 pj_ice_sess_check *vc = &ice->valid_list.checks[j]; 1270 if (vc->lcand->comp_id == comp_id) 1271 break; 1272 } 1273 if (j == ice->valid_list.count) 1343 for (i=0; i < ice->comp_cnt; ++i) { 1344 if (ice->comp[i].valid_check == NULL) 1274 1345 break; 1275 1346 } 1276 1347 1277 if ( comp_id <=ice->comp_cnt) {1348 if (i < ice->comp_cnt) { 1278 1349 /* This component ID doesn't have valid pair. 1279 1350 * Mark ICE as failed. … … 1285 1356 * We should wait until we receive nominated checks. 1286 1357 */ 1358 if (ice->timer.id == TIMER_NONE && 1359 ice->opt.controlled_agent_want_nom_timeout >= 0) 1360 { 1361 pj_time_val delay; 1362 1363 delay.sec = 0; 1364 delay.msec = ice->opt.controlled_agent_want_nom_timeout; 1365 pj_time_val_normalize(&delay); 1366 1367 ice->timer.id = TIMER_CONTROLLED_WAIT_NOM; 1368 pj_timer_heap_schedule(ice->stun_cfg.timer_heap, 1369 &ice->timer, 1370 &delay); 1371 1372 LOG5((ice->obj_name, 1373 "All checks have completed. Controlled agent now " 1374 "waits for nomination from controlling agent " 1375 "(timeout=%d msec)", 1376 ice->opt.controlled_agent_want_nom_timeout)); 1377 } 1287 1378 return PJ_FALSE; 1288 1379 } 1289 } 1290 1291 on_ice_complete(ice, PJNATH_EICEFAILED); 1292 return PJ_TRUE; 1380 1381 /* Unreached */ 1382 1383 } else if (ice->is_nominating) { 1384 /* We are controlling agent and all checks have completed but 1385 * there's at least one component without nominated pair (or 1386 * more likely we don't have any nominated pairs at all). 1387 */ 1388 on_ice_complete(ice, PJNATH_EICEFAILED); 1389 return PJ_TRUE; 1390 1391 } else { 1392 /* We are controlling agent and all checks have completed. If 1393 * we have valid list for every component, then move on to 1394 * sending nominated check, otherwise we have failed. 1395 */ 1396 for (i=0; i<ice->comp_cnt; ++i) { 1397 if (ice->comp[i].valid_check == NULL) 1398 break; 1399 } 1400 1401 if (i < ice->comp_cnt) { 1402 /* At least one component doesn't have a valid check. Mark 1403 * ICE as failed. 1404 */ 1405 on_ice_complete(ice, PJNATH_EICEFAILED); 1406 return PJ_TRUE; 1407 } 1408 1409 /* Now it's time to send connectivity check with nomination 1410 * flag set. 1411 */ 1412 LOG5((ice->obj_name, 1413 "All checks have completed, starting nominated checks now")); 1414 start_nominated_check(ice); 1415 return PJ_FALSE; 1416 } 1417 } 1418 1419 /* If this connectivity check has been successful, scan all components 1420 * and see if they have a valid pair, if we are controlling and we haven't 1421 * started our nominated check yet. 1422 */ 1423 if (check->err_code == PJ_SUCCESS && 1424 ice->role==PJ_ICE_SESS_ROLE_CONTROLLING && 1425 !ice->is_nominating && 1426 ice->timer.id == TIMER_NONE) 1427 { 1428 pj_time_val delay; 1429 1430 for (i=0; i<ice->comp_cnt; ++i) { 1431 if (ice->comp[i].valid_check == NULL) 1432 break; 1433 } 1434 1435 if (i < ice->comp_cnt) { 1436 /* Some components still don't have valid pair, continue 1437 * processing. 1438 */ 1439 return PJ_FALSE; 1440 } 1441 1442 LOG5((ice->obj_name, 1443 "Scheduling nominated check in %d ms", 1444 ice->opt.nominated_check_delay)); 1445 1446 /* All components have valid pair. Let connectivity checks run for 1447 * a little bit more time, then start our nominated check. 1448 */ 1449 delay.sec = 0; 1450 delay.msec = ice->opt.nominated_check_delay; 1451 pj_time_val_normalize(&delay); 1452 1453 ice->timer.id = TIMER_START_NOMINATED_CHECK; 1454 pj_timer_heap_schedule(ice->stun_cfg.timer_heap, &ice->timer, &delay); 1455 return PJ_FALSE; 1293 1456 } 1294 1457 … … 1296 1459 return PJ_FALSE; 1297 1460 } 1298 1299 1461 1300 1462 … … 1431 1593 } 1432 1594 1433 /* Perform check on the specified candidate pair */1595 /* Perform check on the specified candidate pair. */ 1434 1596 static pj_status_t perform_check(pj_ice_sess *ice, 1435 1597 pj_ice_sess_checklist *clist, 1436 unsigned check_id) 1598 unsigned check_id, 1599 pj_bool_t nominate) 1437 1600 { 1438 1601 pj_ice_sess_comp *comp; … … 1482 1645 */ 1483 1646 if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) { 1484 pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg, 1485 PJ_STUN_ATTR_USE_CANDIDATE); 1486 check->nominated = PJ_TRUE; 1647 if (nominate) { 1648 pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg, 1649 PJ_STUN_ATTR_USE_CANDIDATE); 1650 check->nominated = PJ_TRUE; 1651 } 1487 1652 1488 1653 pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, … … 1550 1715 1551 1716 if (check->state == PJ_ICE_SESS_CHECK_STATE_WAITING) { 1552 status = perform_check(ice, clist, i );1717 status = perform_check(ice, clist, i, ice->is_nominating); 1553 1718 if (status != PJ_SUCCESS) { 1554 1719 pj_mutex_unlock(ice->mutex); … … 1569 1734 1570 1735 if (check->state == PJ_ICE_SESS_CHECK_STATE_FROZEN) { 1571 status = perform_check(ice, clist, i );1736 status = perform_check(ice, clist, i, ice->is_nominating); 1572 1737 if (status != PJ_SUCCESS) { 1573 1738 pj_mutex_unlock(ice->mutex); … … 1596 1761 } 1597 1762 1763 1764 /* Start sending connectivity check with USE-CANDIDATE */ 1765 static void start_nominated_check(pj_ice_sess *ice) 1766 { 1767 pj_time_val delay; 1768 unsigned i; 1769 pj_status_t status; 1770 1771 LOG4((ice->obj_name, "Starting nominated check..")); 1772 1773 pj_assert(ice->is_nominating == PJ_FALSE); 1774 1775 /* Stop our timer if it's active */ 1776 if (ice->timer.id == TIMER_START_NOMINATED_CHECK) { 1777 pj_timer_heap_cancel(ice->stun_cfg.timer_heap, &ice->timer); 1778 ice->timer.id = TIMER_NONE; 1779 } 1780 1781 /* For each component, set the check state of valid check with 1782 * highest priority to Waiting (it should have Success state now). 1783 */ 1784 for (i=0; i<ice->comp_cnt; ++i) { 1785 pj_assert(ice->comp[i].nominated_check == NULL); 1786 pj_assert(ice->comp[i].valid_check->err_code == PJ_SUCCESS); 1787 1788 ice->comp[i].valid_check->state = PJ_ICE_SESS_CHECK_STATE_FROZEN; 1789 check_set_state(ice, ice->comp[i].valid_check, 1790 PJ_ICE_SESS_CHECK_STATE_WAITING, PJ_SUCCESS); 1791 } 1792 1793 /* And (re)start the periodic check */ 1794 if (!ice->clist.timer.id) { 1795 ice->clist.timer.id = PJ_TRUE; 1796 delay.sec = delay.msec = 0; 1797 status = pj_timer_heap_schedule(ice->stun_cfg.timer_heap, 1798 &ice->clist.timer, &delay); 1799 if (status != PJ_SUCCESS) { 1800 ice->clist.timer.id = PJ_FALSE; 1801 } 1802 } 1803 1804 ice->is_nominating = PJ_TRUE; 1805 } 1598 1806 1599 1807 /* Timer callback to perform periodic check */ … … 1642 1850 1643 1851 LOG4((ice->obj_name, "Starting ICE check..")); 1852 1853 /* If we are using aggressive nomination, set the is_nominating state */ 1854 if (ice->opt.aggressive) 1855 ice->is_nominating = PJ_TRUE; 1644 1856 1645 1857 /* The agent examines the check list for the first media stream (a … … 1827 2039 LOG4((ice->obj_name, "Resending check because of role conflict")); 1828 2040 check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0); 1829 perform_check(ice, clist, msg_data->data.req.ckid); 2041 perform_check(ice, clist, msg_data->data.req.ckid, 2042 check->nominated); 1830 2043 pj_mutex_unlock(ice->mutex); 1831 2044 return; … … 2313 2526 c->state == PJ_ICE_SESS_CHECK_STATE_WAITING) 2314 2527 { 2528 /* See if we shall nominate this check */ 2529 pj_bool_t nominate = (c->nominated || ice->is_nominating); 2530 2315 2531 LOG5((ice->obj_name, "Performing triggered check for check %d",i)); 2316 perform_check(ice, &ice->clist, i );2532 perform_check(ice, &ice->clist, i, nominate); 2317 2533 2318 2534 } else if (c->state == PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS) { … … 2362 2578 2363 2579 pj_ice_sess_check *c = &ice->clist.checks[ice->clist.count]; 2580 pj_bool_t nominate; 2364 2581 2365 2582 c->lcand = lcand; … … 2370 2587 c->err_code = PJ_SUCCESS; 2371 2588 2589 nominate = (c->nominated || ice->is_nominating); 2590 2372 2591 LOG4((ice->obj_name, "New triggered check added: %d", 2373 2592 ice->clist.count)); 2374 perform_check(ice, &ice->clist, ice->clist.count++ );2593 perform_check(ice, &ice->clist, ice->clist.count++, nominate); 2375 2594 2376 2595 } else { -
pjproject/branches/projects/sipit24/pjnath/src/pjnath/ice_strans.c
r2599 r2705 159 159 pj_ice_strans_cb cb; /**< Application callback. */ 160 160 pj_lock_t *init_lock; /**< Initialization mutex. */ 161 pj_ice_sess_options opt; /**< ICE session options */ 161 162 162 163 pj_ice_sess *ice; /**< ICE session. */ … … 201 202 cfg->stun.port = PJ_STUN_PORT; 202 203 cfg->turn.conn_type = PJ_TURN_TP_UDP; 204 205 cfg->stun.max_host_cands = 64; 203 206 } 204 207 … … 246 249 247 250 /* Create STUN transport if configured */ 248 if (ice_st->cfg.stun.server.slen || !ice_st->cfg.stun.no_host_cands) {251 if (ice_st->cfg.stun.server.slen || ice_st->cfg.stun.max_host_cands) { 249 252 pj_stun_sock_cb stun_sock_cb; 250 253 pj_ice_sess_cand *cand; … … 310 313 } 311 314 312 /* Add local addresses to host candidates, unless no_host_cands313 * flag is set.315 /* Add local addresses to host candidates, unless max_host_cands 316 * is set to zero. 314 317 */ 315 if (ice_st->cfg.stun. no_host_cands == PJ_FALSE) {318 if (ice_st->cfg.stun.max_host_cands) { 316 319 pj_stun_sock_info stun_sock_info; 317 320 unsigned i; … … 322 325 return status; 323 326 324 for (i=0; i<stun_sock_info.alias_cnt; ++i) { 327 for (i=0; i<stun_sock_info.alias_cnt && 328 i<ice_st->cfg.stun.max_host_cands; ++i) 329 { 325 330 char addrinfo[PJ_INET6_ADDRSTRLEN+10]; 326 331 const pj_sockaddr *addr = &stun_sock_info.aliases[i]; … … 444 449 ice_st->obj_name = pool->obj_name; 445 450 ice_st->user_data = user_data; 451 452 pj_ice_sess_options_default(&ice_st->opt); 446 453 447 454 PJ_LOG(4,(ice_st->obj_name, … … 648 655 649 656 /* 657 * Get the value of various options of the ICE stream transport. 658 */ 659 PJ_DEF(pj_status_t) pj_ice_strans_get_options( pj_ice_strans *ice_st, 660 pj_ice_sess_options *opt) 661 { 662 PJ_ASSERT_RETURN(ice_st && opt, PJ_EINVAL); 663 pj_memcpy(opt, &ice_st->opt, sizeof(*opt)); 664 return PJ_SUCCESS; 665 } 666 667 /* 668 * Specify various options for this ICE stream transport. 669 */ 670 PJ_DEF(pj_status_t) pj_ice_strans_set_options(pj_ice_strans *ice_st, 671 const pj_ice_sess_options *opt) 672 { 673 PJ_ASSERT_RETURN(ice_st && opt, PJ_EINVAL); 674 pj_memcpy(&ice_st->opt, opt, sizeof(*opt)); 675 if (ice_st->ice) 676 pj_ice_sess_set_options(ice_st->ice, &ice_st->opt); 677 return PJ_SUCCESS; 678 } 679 680 /* 650 681 * Create ICE! 651 682 */ … … 682 713 /* Associate user data */ 683 714 ice_st->ice->user_data = (void*)ice_st; 715 716 /* Set options */ 717 pj_ice_sess_set_options(ice_st->ice, &ice_st->opt); 684 718 685 719 /* If default candidate for components are SRFLX one, upload a custom -
pjproject/branches/projects/sipit24/pjsip-apps/src/pjsua/pjsua_app.c
r2704 r2705 4729 4729 status = pjmedia_transport_udp_create3(pjsua_get_pjmedia_endpt(), 4730 4730 pj_AF_INET6(), 4731 NULL,4731 app_config.rtp_cfg.public_addr.ptr, 4732 4732 &app_config.rtp_cfg.bound_addr, 4733 4733 port, -
pjproject/branches/projects/sipit24/pjsip-apps/src/samples/icedemo.c
r2600 r2705 40 40 unsigned comp_cnt; 41 41 pj_str_t ns; 42 pj_bool_t no_host; 42 int max_host; 43 pj_bool_t regular; 43 44 pj_str_t stun_srv; 44 45 pj_str_t turn_srv; … … 307 308 /* -= Start initializing ICE stream transport config =- */ 308 309 309 /* Disable host candidates? */ 310 icedemo.ice_cfg.stun.no_host_cands = icedemo.opt.no_host; 310 /* Maximum number of host candidates */ 311 if (icedemo.opt.max_host != -1) 312 icedemo.ice_cfg.stun.max_host_cands = icedemo.opt.max_host; 311 313 312 314 /* Configure STUN/srflx candidate resolution */ … … 375 377 { 376 378 pj_ice_strans_cb icecb; 379 pj_ice_sess_options opt; 377 380 pj_status_t status; 378 381 … … 399 402 else 400 403 PJ_LOG(3,(THIS_FILE, "ICE instance successfully created")); 404 405 status = pj_ice_strans_get_options(icedemo.icest, &opt); 406 pj_assert(status == PJ_SUCCESS); 407 408 if (icedemo.opt.regular) 409 opt.aggressive = PJ_FALSE; 410 else 411 opt.aggressive = PJ_TRUE; 412 413 status = pj_ice_strans_set_options(icedemo.icest, &opt); 414 pj_assert(status == PJ_SUCCESS); 401 415 } 402 416 … … 961 975 */ 962 976 963 if (comp_id >pj_ice_strans_get_running_comp_cnt(icedemo.icest)) {977 if (comp_id<1||comp_id>pj_ice_strans_get_running_comp_cnt(icedemo.icest)) { 964 978 PJ_LOG(1,(THIS_FILE, "Error: invalid component ID")); 965 979 return; … … 1138 1152 puts(" --nameserver, -n IP Configure nameserver to activate DNS SRV"); 1139 1153 puts(" resolution"); 1140 puts(" --no-host, -H Disable host candidates"); 1154 puts(" --max-host, -H N Set max number of host candidates to N"); 1155 puts(" --regular, -R Use regular nomination (default aggressive)"); 1141 1156 puts(" --help, -h Display this screen."); 1142 1157 puts(""); … … 1166 1181 { "comp-cnt", 1, 0, 'c'}, 1167 1182 { "nameserver", 1, 0, 'n'}, 1168 { " no-host", 0, 0, 'H'},1183 { "max-host", 1, 0, 'H'}, 1169 1184 { "help", 0, 0, 'h'}, 1170 1185 { "stun-srv", 1, 0, 's'}, … … 1173 1188 { "turn-username", 1, 0, 'u'}, 1174 1189 { "turn-password", 1, 0, 'p'}, 1175 { "turn-fingerprint", 0, 0, 'F'} 1190 { "turn-fingerprint", 0, 0, 'F'}, 1191 { "regular", 0, 0, 'R'} 1176 1192 }; 1177 1193 int c, opt_id; … … 1179 1195 1180 1196 icedemo.opt.comp_cnt = 1; 1181 1182 while((c=pj_getopt_long(argc,argv, "n:s:t:u:p:HhTF", long_options, &opt_id))!=-1) { 1197 icedemo.opt.max_host = -1; 1198 1199 while((c=pj_getopt_long(argc,argv, "c:n:s:t:u:p:H:hTFR", long_options, &opt_id))!=-1) { 1183 1200 switch (c) { 1184 1201 case 'c': … … 1193 1210 break; 1194 1211 case 'H': 1195 icedemo.opt. no_host = PJ_TRUE;1212 icedemo.opt.max_host = atoi(pj_optarg); 1196 1213 break; 1197 1214 case 'h': … … 1216 1233 icedemo.opt.turn_fingerprint = PJ_TRUE; 1217 1234 break; 1235 case 'R': 1236 icedemo.opt.regular = PJ_TRUE; 1237 break; 1218 1238 default: 1219 1239 printf("Argument \"%s\" is not valid. Use -h to see help", -
pjproject/branches/projects/sipit24/pjsip/src/pjsua-lib/pjsua_media.c
r2679 r2705 811 811 ice_cfg.stun.port = pj_sockaddr_get_port(&pjsua_var.stun_srv); 812 812 } 813 ice_cfg.stun.no_host_cands = pjsua_var.media_cfg.ice_no_host_cands; 813 if (pjsua_var.media_cfg.ice_no_host_cands) 814 ice_cfg.stun.max_host_cands = 0; 814 815 815 816 /* Configure TURN settings */
Note: See TracChangeset
for help on using the changeset viewer.