Changeset 1990
- Timestamp:
- Jun 6, 2008 2:51:48 PM (16 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r1976 r1990 171 171 puts (""); 172 172 puts ("Media Options:"); 173 puts (" --use-ice Enable ICE (default:no)");174 173 puts (" --add-codec=name Manually add codec (default is to enable all)"); 175 174 puts (" --dis-codec=name Disable codec (can be specified multiple times)"); … … 189 188 puts (" --rec-file=file Open file recorder (extension can be .wav or .mp3"); 190 189 puts (" --auto-rec Automatically record conversation"); 191 puts (" --rtp-port=N Base port to try for RTP (default=4000)");192 190 puts (" --quality=N Specify media quality (0-10, default=6)"); 193 191 puts (" --ptime=MSEC Override codec ptime to MSEC (default=specific)"); … … 195 193 puts (" --ec-tail=MSEC Set echo canceller tail length (default=256)"); 196 194 puts (" --ilbc-mode=MODE Set iLBC codec mode (20 or 30, default is 20)"); 195 puts (" --capture-dev=id Audio capture device ID (default=-1)"); 196 puts (" --playback-dev=id Audio playback device ID (default=-1)"); 197 198 puts (""); 199 puts ("Media Transport Options:"); 200 puts (" --use-ice Enable ICE (default:no)"); 201 puts (" --ice-no-host Disable ICE host candidates"); 202 puts (" --rtp-port=N Base port to try for RTP (default=4000)"); 197 203 puts (" --rx-drop-pct=PCT Drop PCT percent of RX RTP (for pkt lost sim, default: 0)"); 198 204 puts (" --tx-drop-pct=PCT Drop PCT percent of TX RTP (for pkt lost sim, default: 0)"); 199 puts (" --capture-dev=id Audio capture device ID (default=-1)"); 200 puts (" --playback-dev=id Audio playback device ID (default=-1)"); 201 205 puts (" --use-turn Enable TURN relay with ICE (default:no)"); 206 puts (" --turn-srv Domain or host name of TURN server (\"NAME:PORT\" format)"); 207 puts (" --turn-tcp Use TCP connection to TURN server (default no)"); 208 puts (" --turn-user TURN username"); 209 puts (" --turn-passwd TURN password"); 202 210 203 211 puts (""); … … 393 401 OPT_AUTO_CONF, OPT_CLOCK_RATE, OPT_SND_CLOCK_RATE, OPT_STEREO, 394 402 OPT_USE_ICE, OPT_USE_SRTP, OPT_SRTP_SECURE, 403 OPT_USE_TURN,OPT_ICE_NO_HOST, OPT_TURN_SRV, OPT_TURN_TCP, 404 OPT_TURN_USER, OPT_TURN_PASSWD, 395 405 OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC, 396 406 OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC, … … 452 462 { "rec-file", 1, 0, OPT_REC_FILE}, 453 463 { "rtp-port", 1, 0, OPT_RTP_PORT}, 464 454 465 { "use-ice", 0, 0, OPT_USE_ICE}, 466 { "use-turn", 0, 0, OPT_USE_TURN}, 467 { "ice-no-host",0, 0, OPT_ICE_NO_HOST}, 468 { "turn-srv", 1, 0, OPT_TURN_SRV}, 469 { "turn-tcp", 0, 0, OPT_TURN_TCP}, 470 { "turn-user", 1, 0, OPT_TURN_USER}, 471 { "turn-passwd",1, 0, OPT_TURN_PASSWD}, 472 455 473 #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 456 474 { "use-srtp", 1, 0, OPT_USE_SRTP}, … … 826 844 break; 827 845 846 case OPT_USE_TURN: 847 cfg->media_cfg.enable_turn = PJ_TRUE; 848 break; 849 850 case OPT_ICE_NO_HOST: 851 cfg->media_cfg.ice_no_host_cands = PJ_TRUE; 852 break; 853 854 case OPT_TURN_SRV: 855 cfg->media_cfg.turn_server = pj_str(pj_optarg); 856 break; 857 858 case OPT_TURN_TCP: 859 cfg->media_cfg.turn_conn_type = PJ_TURN_TP_TCP; 860 break; 861 862 case OPT_TURN_USER: 863 cfg->media_cfg.turn_auth_cred.type = PJ_STUN_AUTH_CRED_STATIC; 864 cfg->media_cfg.turn_auth_cred.data.static_cred.realm = pj_str("*"); 865 cfg->media_cfg.turn_auth_cred.data.static_cred.username = pj_str(pj_optarg); 866 break; 867 868 case OPT_TURN_PASSWD: 869 cfg->media_cfg.turn_auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; 870 cfg->media_cfg.turn_auth_cred.data.static_cred.data = pj_str(pj_optarg); 871 break; 872 828 873 #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 829 874 case OPT_USE_SRTP: … … 1360 1405 #endif 1361 1406 1362 /* Media */1407 /* Media Transport*/ 1363 1408 if (config->media_cfg.enable_ice) 1364 1409 pj_strcat2(&cfg, "--use-ice\n"); 1410 1411 if (config->media_cfg.enable_turn) 1412 pj_strcat2(&cfg, "--use-turn\n"); 1413 1414 if (config->media_cfg.ice_no_host_cands) 1415 pj_strcat2(&cfg, "--ice-no-host\n"); 1416 1417 if (config->media_cfg.turn_server.slen) { 1418 pj_ansi_sprintf(line, "--turn-srv %.*s\n", 1419 (int)config->media_cfg.turn_server.slen, 1420 config->media_cfg.turn_server.ptr); 1421 pj_strcat2(&cfg, line); 1422 } 1423 1424 if (config->media_cfg.turn_conn_type == PJ_TURN_TP_TCP) 1425 pj_strcat2(&cfg, "--turn-tcp\n"); 1426 1427 if (config->media_cfg.turn_auth_cred.data.static_cred.username.slen) { 1428 pj_ansi_sprintf(line, "--turn-user %.*s\n", 1429 (int)config->media_cfg.turn_auth_cred.data.static_cred.username.slen, 1430 config->media_cfg.turn_auth_cred.data.static_cred.username.ptr); 1431 pj_strcat2(&cfg, line); 1432 } 1433 1434 if (config->media_cfg.turn_auth_cred.data.static_cred.data.slen) { 1435 pj_ansi_sprintf(line, "--turn-passwd %.*s\n", 1436 (int)config->media_cfg.turn_auth_cred.data.static_cred.data.slen, 1437 config->media_cfg.turn_auth_cred.data.static_cred.data.ptr); 1438 pj_strcat2(&cfg, line); 1439 } 1440 1441 /* Media */ 1365 1442 if (config->null_audio) 1366 1443 pj_strcat2(&cfg, "--null-audio\n"); -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r1951 r1990 1029 1029 /** 1030 1030 * Specify domain name to be resolved with DNS SRV resolution to get the 1031 * address of the STUN server s. Alternatively application may specify1032 * \a stun_host and \a stun_relay_hostinstead.1031 * address of the STUN server. Alternatively application may specify 1032 * \a stun_host instead. 1033 1033 * 1034 1034 * If DNS SRV resolution failed for this domain, then DNS A resolution … … 1042 1042 */ 1043 1043 pj_str_t stun_host; 1044 1045 /**1046 * Specify STUN relay server to be used.1047 */1048 pj_str_t stun_relay_host;1049 1044 1050 1045 /** … … 3887 3882 3888 3883 /** 3889 * Enable ICE media relay. 3890 */ 3891 pj_bool_t enable_relay; 3884 * Disable ICE host candidates. 3885 */ 3886 pj_bool_t ice_no_host_cands; 3887 3888 /** 3889 * Enable TURN relay candidate in ICE. 3890 */ 3891 pj_bool_t enable_turn; 3892 3893 /** 3894 * Specify TURN domain name or host name, in in "DOMAIN:PORT" or 3895 * "HOST:PORT" format. 3896 */ 3897 pj_str_t turn_server; 3898 3899 /** 3900 * Specify the connection type to be used to the TURN server. Valid 3901 * values are PJ_TURN_TP_UDP or PJ_TURN_TP_TCP. 3902 * 3903 * Default: PJ_TURN_TP_UDP 3904 */ 3905 pj_turn_tp_type turn_conn_type; 3906 3907 /** 3908 * Specify the credential to authenticate with the TURN server. 3909 */ 3910 pj_stun_auth_cred turn_auth_cred; 3892 3911 }; 3893 3912 -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r1889 r1990 53 53 call was triggered by xfer. */ 54 54 pjmedia_transport *med_tp; /**< Current media transport. */ 55 pj_status_t med_tp_st; /**< Media transport status. */ 55 56 pjmedia_transport *med_orig; /**< Original media transport */ 56 57 pj_timer_entry refresh_tm;/**< Timer to send re-INVITE. */ -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r1898 r1990 114 114 pj_strdup_with_null(pool, &dst->stun_domain, &src->stun_domain); 115 115 pj_strdup_with_null(pool, &dst->stun_host, &src->stun_host); 116 pj_strdup_with_null(pool, &dst->stun_relay_host, &src->stun_relay_host);117 116 } 118 117 … … 173 172 cfg->ec_tail_len = PJSUA_DEFAULT_EC_TAIL_LEN; 174 173 cfg->jb_init = cfg->jb_min_pre = cfg->jb_max_pre = cfg->jb_max = -1; 174 175 cfg->turn_conn_type = PJ_TURN_TP_UDP; 175 176 } 176 177 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r1970 r1990 37 37 38 38 39 static void pjsua_media_config_dup(pj_pool_t *pool, 40 pjsua_media_config *dst, 41 const pjsua_media_config *src) 42 { 43 pj_memcpy(dst, src, sizeof(*src)); 44 pj_strdup(pool, &dst->turn_server, &src->turn_server); 45 pj_stun_auth_cred_dup(pool, &dst->turn_auth_cred, &src->turn_auth_cred); 46 } 47 39 48 /** 40 49 * Init media subsystems. … … 50 59 51 60 /* Copy configuration */ 52 pj _memcpy(&pjsua_var.media_cfg, cfg, sizeof(*cfg));61 pjsua_media_config_dup(pjsua_var.pool, &pjsua_var.media_cfg, cfg); 53 62 54 63 /* Normalize configuration */ … … 582 591 583 592 /* This callback is called when ICE negotiation completes */ 584 static void on_ice_complete(pjmedia_transport *tp, pj_status_t result) 585 { 586 unsigned id, c; 593 static void on_ice_complete(pjmedia_transport *tp, 594 pj_ice_strans_op op, 595 pj_status_t result) 596 { 597 unsigned id; 587 598 pj_bool_t found = PJ_FALSE; 588 599 589 /* We're only interested with failure case */ 590 if (result == PJ_SUCCESS) 600 /* Find call which has this media transport */ 601 602 PJSUA_LOCK(); 603 604 for (id=0; id<pjsua_var.ua_cfg.max_calls; ++id) { 605 if (pjsua_var.calls[id].med_tp == tp || 606 pjsua_var.calls[id].med_orig == tp) 607 { 608 found = PJ_TRUE; 609 break; 610 } 611 } 612 613 PJSUA_UNLOCK(); 614 615 if (!found) 591 616 return; 592 617 593 /* Find call which has this media transport */ 594 595 PJSUA_LOCK(); 596 597 for (id=0, c=0; id<PJSUA_MAX_CALLS && c<pjsua_var.call_cnt; ++id) { 598 pjsua_call *call = &pjsua_var.calls[id]; 599 if (call->inv) { 600 ++c; 601 602 if (call->med_tp == tp) { 603 call->media_st = PJSUA_CALL_MEDIA_ERROR; 604 call->media_dir = PJMEDIA_DIR_NONE; 605 found = PJ_TRUE; 606 break; 618 switch (op) { 619 case PJ_ICE_STRANS_OP_INIT: 620 pjsua_var.calls[id].med_tp_st = result; 621 break; 622 case PJ_ICE_STRANS_OP_NEGOTIATION: 623 if (result != PJ_SUCCESS) { 624 pjsua_var.calls[id].media_st = PJSUA_CALL_MEDIA_ERROR; 625 pjsua_var.calls[id].media_dir = PJMEDIA_DIR_NONE; 626 627 if (pjsua_var.ua_cfg.cb.on_call_media_state) { 628 pjsua_var.ua_cfg.cb.on_call_media_state(id); 607 629 } 608 630 } 609 } 610 611 PJSUA_UNLOCK(); 612 613 if (found && pjsua_var.ua_cfg.cb.on_call_media_state) { 614 pjsua_var.ua_cfg.cb.on_call_media_state(id); 615 } 616 } 617 631 break; 632 } 633 } 634 635 636 /* Parse "HOST:PORT" format */ 637 static pj_status_t parse_host_port(const pj_str_t *host_port, 638 pj_str_t *host, pj_uint16_t *port) 639 { 640 pj_str_t str_port; 641 642 str_port.ptr = pj_strchr(host_port, ':'); 643 if (str_port.ptr != NULL) { 644 int iport; 645 646 host->ptr = host_port->ptr; 647 host->slen = (str_port.ptr - host->ptr); 648 str_port.ptr++; 649 str_port.slen = host_port->slen - host->slen - 1; 650 iport = (int)pj_strtoul(&str_port); 651 if (iport < 1 || iport > 65535) 652 return PJ_EINVAL; 653 *port = (pj_uint16_t)iport; 654 } else { 655 *host = *host_port; 656 *port = 0; 657 } 658 659 return PJ_SUCCESS; 660 } 618 661 619 662 /* Create ICE media transports (when ice is enabled) */ 620 static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg) 621 { 663 static pj_status_t create_ice_media_transports(void) 664 { 665 char stunip[PJ_INET6_ADDRSTRLEN]; 666 pj_ice_strans_cfg ice_cfg; 622 667 unsigned i; 623 pj_sockaddr_in addr;624 668 pj_status_t status; 625 669 … … 631 675 } 632 676 633 pj_sockaddr_in_init(&addr, 0, (pj_uint16_t)cfg->port); 677 /* Create ICE stream transport configuration */ 678 pj_ice_strans_cfg_default(&ice_cfg); 679 pj_stun_config_init(&ice_cfg.stun_cfg, &pjsua_var.cp.factory, 0, 680 pjsip_endpt_get_ioqueue(pjsua_var.endpt), 681 pjsip_endpt_get_timer_heap(pjsua_var.endpt)); 682 683 ice_cfg.af = pj_AF_INET(); 684 ice_cfg.resolver = pjsua_var.resolver; 685 686 /* Configure STUN settings */ 687 if (pj_sockaddr_has_addr(&pjsua_var.stun_srv)) { 688 pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0); 689 ice_cfg.stun.server = pj_str(stunip); 690 ice_cfg.stun.port = pj_sockaddr_get_port(&pjsua_var.stun_srv); 691 } 692 ice_cfg.stun.no_host_cands = pjsua_var.media_cfg.ice_no_host_cands; 693 694 /* Configure TURN settings */ 695 if (pjsua_var.media_cfg.enable_turn) { 696 status = parse_host_port(&pjsua_var.media_cfg.turn_server, 697 &ice_cfg.turn.server, 698 &ice_cfg.turn.port); 699 if (status != PJ_SUCCESS || ice_cfg.turn.server.slen == 0) { 700 PJ_LOG(1,(THIS_FILE, "Invalid TURN server setting")); 701 return PJ_EINVAL; 702 } 703 if (ice_cfg.turn.port == 0) 704 ice_cfg.turn.port = 3479; 705 ice_cfg.turn.conn_type = pjsua_var.media_cfg.turn_conn_type; 706 pj_memcpy(&ice_cfg.turn.auth_cred, 707 &pjsua_var.media_cfg.turn_auth_cred, 708 sizeof(ice_cfg.turn.auth_cred)); 709 } 634 710 635 711 /* Create each media transport */ 636 712 for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) { 637 pj_ice_strans_comp comp;638 713 pjmedia_ice_cb ice_cb; 639 int next_port;640 714 char name[32]; 641 #if PJMEDIA_ADVERTISE_RTCP 642 enum { COMP_CNT=2 }; 643 #else 644 enum { COMP_CNT=1 }; 645 #endif 715 unsigned comp_cnt; 646 716 647 717 pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb)); 648 718 ice_cb.on_ice_complete = &on_ice_complete; 649 650 719 pj_ansi_snprintf(name, sizeof(name), "icetp%02d", i); 651 652 status = pjmedia_ice_create(pjsua_var.med_endpt, name, COMP_CNT, 653 &pjsua_var.stun_cfg, &ice_cb, 720 pjsua_var.calls[i].med_tp_st = PJ_EPENDING; 721 722 comp_cnt = 1; 723 if (PJMEDIA_ADVERTISE_RTCP) 724 ++comp_cnt; 725 726 status = pjmedia_ice_create(pjsua_var.med_endpt, name, comp_cnt, 727 &ice_cfg, &ice_cb, 654 728 &pjsua_var.calls[i].med_tp); 655 729 if (status != PJ_SUCCESS) { … … 659 733 } 660 734 735 /* Wait until transport is initialized, or time out */ 736 PJSUA_UNLOCK(); 737 while (pjsua_var.calls[i].med_tp_st == PJ_EPENDING) { 738 pjsua_handle_events(100); 739 } 740 PJSUA_LOCK(); 741 if (pjsua_var.calls[i].med_tp_st != PJ_SUCCESS) { 742 pjsua_perror(THIS_FILE, "Error initializing ICE media transport", 743 pjsua_var.calls[i].med_tp_st); 744 status = pjsua_var.calls[i].med_tp_st; 745 goto on_error; 746 } 747 661 748 pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp, 662 749 PJMEDIA_DIR_ENCODING, … … 666 753 PJMEDIA_DIR_DECODING, 667 754 pjsua_var.media_cfg.rx_drop_pct); 668 669 status = pjmedia_ice_start_init(pjsua_var.calls[i].med_tp, 0, &addr,670 &pjsua_var.stun_srv.ipv4, NULL);671 if (status != PJ_SUCCESS) {672 pjsua_perror(THIS_FILE, "Error starting ICE transport",673 status);674 goto on_error;675 }676 677 pjmedia_ice_get_comp(pjsua_var.calls[i].med_tp, 1, &comp);678 next_port = pj_ntohs(comp.local_addr.ipv4.sin_port);679 next_port += 2;680 addr.sin_port = pj_htons((pj_uint16_t)next_port);681 }682 683 /* Wait until all ICE transports are ready */684 for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {685 686 /* Wait until interface status is PJ_SUCCESS */687 for (;;) {688 status = pjmedia_ice_get_init_status(pjsua_var.calls[i].med_tp);689 if (status == PJ_EPENDING)690 pjsua_handle_events(100);691 else692 break;693 }694 695 if (status != PJ_SUCCESS) {696 pjsua_perror(THIS_FILE,697 "Error adding STUN address to ICE media transport",698 status);699 goto on_error;700 }701 702 755 } 703 756 … … 745 798 746 799 if (pjsua_var.media_cfg.enable_ice) { 747 status = create_ice_media_transports( &cfg);800 status = create_ice_media_transports(); 748 801 } else { 749 802 status = create_udp_media_transports(&cfg); … … 897 950 pjsua_call *call = &pjsua_var.calls[call_id]; 898 951 899 pjmedia_transport_media_stop(call->med_tp); 952 //see ticket #525 953 //pjmedia_transport_media_stop(call->med_tp); 900 954 901 955 if (call->conf_slot != PJSUA_INVALID_ID) {
Note: See TracChangeset
for help on using the changeset viewer.