Ignore:
Timestamp:
Jun 6, 2008 2:51:48 PM (17 years ago)
Author:
bennylp
Message:

More ticket #485: added TURN support in PJSUA-LIB API

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r1970 r1990  
    3737 
    3838 
     39static 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 
    3948/** 
    4049 * Init media subsystems. 
     
    5059 
    5160    /* 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); 
    5362 
    5463    /* Normalize configuration */ 
     
    582591 
    583592/* 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; 
     593static void on_ice_complete(pjmedia_transport *tp,  
     594                            pj_ice_strans_op op, 
     595                            pj_status_t result) 
     596{ 
     597    unsigned id; 
    587598    pj_bool_t found = PJ_FALSE; 
    588599 
    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) 
    591616        return; 
    592617 
    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); 
    607629            } 
    608630        } 
    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 */ 
     637static 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} 
    618661 
    619662/* Create ICE media transports (when ice is enabled) */ 
    620 static pj_status_t create_ice_media_transports(pjsua_transport_config *cfg) 
    621 { 
     663static pj_status_t create_ice_media_transports(void) 
     664{ 
     665    char stunip[PJ_INET6_ADDRSTRLEN]; 
     666    pj_ice_strans_cfg ice_cfg; 
    622667    unsigned i; 
    623     pj_sockaddr_in addr; 
    624668    pj_status_t status; 
    625669 
     
    631675    } 
    632676 
    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    } 
    634710 
    635711    /* Create each media transport */ 
    636712    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) { 
    637         pj_ice_strans_comp comp; 
    638713        pjmedia_ice_cb ice_cb; 
    639         int next_port; 
    640714        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; 
    646716 
    647717        pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb)); 
    648718        ice_cb.on_ice_complete = &on_ice_complete; 
    649  
    650719        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, 
    654728                                    &pjsua_var.calls[i].med_tp); 
    655729        if (status != PJ_SUCCESS) { 
     
    659733        } 
    660734 
     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 
    661748        pjmedia_transport_simulate_lost(pjsua_var.calls[i].med_tp, 
    662749                                        PJMEDIA_DIR_ENCODING, 
     
    666753                                        PJMEDIA_DIR_DECODING, 
    667754                                        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             else 
    692                 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  
    702755    } 
    703756 
     
    745798 
    746799    if (pjsua_var.media_cfg.enable_ice) { 
    747         status = create_ice_media_transports(&cfg); 
     800        status = create_ice_media_transports(); 
    748801    } else { 
    749802        status = create_udp_media_transports(&cfg); 
     
    897950    pjsua_call *call = &pjsua_var.calls[call_id]; 
    898951 
    899     pjmedia_transport_media_stop(call->med_tp); 
     952    //see ticket #525 
     953    //pjmedia_transport_media_stop(call->med_tp); 
    900954 
    901955    if (call->conf_slot != PJSUA_INVALID_ID) { 
Note: See TracChangeset for help on using the changeset viewer.