Changeset 1989


Ignore:
Timestamp:
Jun 6, 2008 2:50:13 PM (16 years ago)
Author:
bennylp
Message:

More ticket #485: major modification in transport_ice to support new ICE stream transport API

Location:
pjproject/trunk/pjmedia
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/transport_ice.h

    r1735 r1989  
    4949     * 
    5050     * @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. 
    5253     */ 
    5354    void    (*on_ice_complete)(pjmedia_transport *tp, 
     55                               pj_ice_strans_op op, 
    5456                               pj_status_t status); 
    5557 
     
    6365 *                      for logging purposes. 
    6466 * @param comp_cnt      Number of components to be created. 
    65  * @param stun_cfg      Pointer to STUN configuration settings. 
     67 * @param cfg           Pointer to configuration settings. 
    6668 * @param cb            Optional callbacks. 
    6769 * @param p_tp          Pointer to receive the media transport instance. 
     
    7274                                        const char *name, 
    7375                                        unsigned comp_cnt, 
    74                                         pj_stun_config *stun_cfg, 
     76                                        const pj_ice_strans_cfg *cfg, 
    7577                                        const pjmedia_ice_cb *cb, 
    7678                                        pjmedia_transport **p_tp); 
    77  
    78  
    79 /** 
    80  * Start the initialization process of this media transport. This function 
    81  * will gather the transport addresses to be registered to ICE session as 
    82  * candidates. If STUN is configured, this will start the STUN Binding or 
    83  * Allocate request to get the STUN server reflexive or relayed address. 
    84  * This function will return immediately, and application should poll the 
    85  * 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 PJNATH  
    89  *                      documentation. 
    90  * @param start_addr    Local address where socket will be bound to. This 
    91  *                      address will be used as follows: 
    92  *                      - if the value is NULL, then socket will be bound 
    93  *                        to any available port. 
    94  *                      - if the value is not NULL, then if the port number 
    95  *                        is not zero, it will used as the starting port  
    96  *                        where the socket will be bound to. If bind() to 
    97  *                        this port fails, this function will try to bind 
    98  *                        to port+2, repeatedly until it succeeded. 
    99  *                        If application doesn't want this function to  
    100  *                        retry binding the socket to other port, it can 
    101  *                        specify PJ_ICE_ST_OPT_NO_PORT_RETRY option. 
    102  *                      - if the value is not NULL, then if the address 
    103  *                        is not INADDR_ANY, this function will bind the 
    104  *                        socket to this particular interface only, and 
    105  *                        no other host candidates will be added for this 
    106  *                        socket. 
    107  * @param stun_srv      Address of the STUN server, or NULL if STUN server 
    108  *                      reflexive mapping is not to be used. 
    109  * @param turn_srv      Address of the TURN server, or NULL if TURN relay 
    110  *                      is not to be used. 
    111  * 
    112  * @return              PJ_SUCCESS when the initialization process has started 
    113  *                      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 resolved 
    127  *                      successfully, PJ_EPENDING if transport resolution 
    128  *                      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 the 
    139  *                      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  
    16379 
    16480PJ_END_DECL 
  • pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c

    r1944 r1989  
    3030{ 
    3131    pjmedia_transport    base; 
     32    pj_pool_t           *pool; 
     33    int                  af; 
     34    unsigned             comp_cnt; 
    3235    pj_ice_strans       *ice_st; 
    3336    pjmedia_ice_cb       cb; 
    3437    unsigned             media_option; 
    3538 
    36     pj_time_val          start_ice; 
    37      
    3839    void                *stream; 
    3940    pj_sockaddr_in       remote_rtp; 
     
    8586                                       unsigned options, 
    8687                                       pjmedia_sdp_session *sdp_local, 
    87                                        const pjmedia_sdp_session *sdp_remote, 
     88                                       const pjmedia_sdp_session *rem_sdp, 
    8889                                       unsigned media_index); 
    8990static pj_status_t transport_media_start (pjmedia_transport *tp, 
    9091                                       pj_pool_t *pool, 
    9192                                       pjmedia_sdp_session *sdp_local, 
    92                                        const pjmedia_sdp_session *sdp_remote, 
     93                                       const pjmedia_sdp_session *rem_sdp, 
    9394                                       unsigned media_index); 
    9495static pj_status_t transport_media_stop(pjmedia_transport *tp); 
     
    101102 * And these are ICE callbacks. 
    102103 */ 
    103 static void ice_on_rx_data(pj_ice_strans *ice_st, unsigned comp_id,  
     104static void ice_on_rx_data(pj_ice_strans *ice_st,  
     105                           unsigned comp_id,  
    104106                           void *pkt, pj_size_t size, 
    105107                           const pj_sockaddr_t *src_addr, 
    106108                           unsigned src_addr_len); 
    107109static void ice_on_ice_complete(pj_ice_strans *ice_st,  
     110                                pj_ice_strans_op op, 
    108111                                pj_status_t status); 
    109112 
     
    135138                                       const char *name, 
    136139                                       unsigned comp_cnt, 
    137                                        pj_stun_config *stun_cfg, 
     140                                       const pj_ice_strans_cfg *cfg, 
    138141                                       const pjmedia_ice_cb *cb, 
    139142                                       pjmedia_transport **p_tp) 
    140143{ 
    141     pj_ice_strans *ice_st; 
     144    pj_pool_t *pool; 
    142145    pj_ice_strans_cb ice_st_cb; 
    143146    struct transport_ice *tp_ice; 
    144147    pj_status_t status; 
    145148 
    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; 
    147168 
    148169    /* Configure ICE callbacks */ 
     
    152173 
    153174    /* 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; 
    157180        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    } 
    171182 
    172183    /* Done */ 
    173     if (p_tp) 
    174         *p_tp = &tp_ice->base; 
    175  
    176184    return PJ_SUCCESS; 
    177185} 
    178186 
    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 */ 
     188static 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} 
    264229 
    265230/* 
     
    268233 */ 
    269234static pj_status_t transport_media_create(pjmedia_transport *tp, 
    270                                        pj_pool_t *pool, 
    271                                        unsigned options, 
    272                                        pjmedia_sdp_session *sdp_local, 
    273                                        const pjmedia_sdp_session *sdp_remote, 
    274                                        unsigned media_index) 
     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) 
    275240{ 
    276241    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; 
    282244    pj_status_t status; 
    283245 
     
    285247 
    286248    /* Validate media transport */ 
    287     /* By now, this transport only support RTP/AVP transport */ 
     249    /* For now, this transport only support RTP/AVP transport */ 
    288250    if ((tp_ice->media_option & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) { 
    289251        pjmedia_sdp_media *m_rem, *m_loc; 
    290252 
    291         m_rem = sdp_remote? sdp_remote->media[media_index] : NULL; 
     253        m_rem = rem_sdp? rem_sdp->media[media_index] : NULL; 
    292254        m_loc = sdp_local->media[media_index]; 
    293255 
     
    300262    } 
    301263 
     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 
    302286    /* 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        } 
    379349    } 
    380350 
    381351    /* Done */ 
    382352    return PJ_SUCCESS; 
    383  
    384353} 
    385354 
     
    412381        goto on_return; 
    413382    } 
    414     cand->comp_id = atoi(token); 
     383    cand->comp_id = (pj_uint8_t) atoi(token); 
    415384 
    416385    /* Transport */ 
     
    501470static void set_no_ice(struct transport_ice *tp_ice, const char *reason) 
    502471{ 
    503     PJ_LOG(4,(tp_ice->ice_st->obj_name,  
     472    PJ_LOG(4,(tp_ice->base.name,  
    504473              "Disabling local ICE, reason=%s", reason)); 
    505474    transport_media_stop(&tp_ice->base); 
     
    513482                                         pj_pool_t *pool, 
    514483                                         pjmedia_sdp_session *sdp_local, 
    515                                          const pjmedia_sdp_session *sdp_remote, 
     484                                         const pjmedia_sdp_session *rem_sdp, 
    516485                                         unsigned media_index) 
    517486{ 
     
    529498    pj_status_t status; 
    530499 
    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]; 
    535504 
    536505    /* Validate media transport */ 
     
    539508        pjmedia_sdp_media *m_rem, *m_loc; 
    540509 
    541         m_rem = sdp_remote->media[media_index]; 
     510        m_rem = rem_sdp->media[media_index]; 
    542511        m_loc = sdp_local->media[media_index]; 
    543512 
     
    556525    conn = sdp_med->conn; 
    557526    if (conn == NULL) 
    558         conn = sdp_remote->conn; 
     527        conn = rem_sdp->conn; 
    559528 
    560529    if (conn == NULL) { 
     
    571540    if (attr == NULL) { 
    572541        /* 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, 
    574543                                      "ice-ufrag", NULL); 
    575544        if (attr == NULL) { 
     
    585554    if (attr == NULL) { 
    586555        /* 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, 
    588557                                      "ice-pwd", NULL); 
    589558        if (attr == NULL) { 
     
    654623    } 
    655624 
    656     /* Mark start time */ 
    657     pj_gettimeofday(&tp_ice->start_ice); 
    658  
    659625    /* If our role was controlled but it turns out that remote is  
    660626     * a lite implementation, change our role to controlling. 
    661627     */ 
    662628    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) 
    664630    { 
    665         pj_ice_sess_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); 
    667633    } 
    668634 
    669635    /* 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); 
    671638} 
    672639 
     
    683650{ 
    684651    struct transport_ice *tp_ice = (struct transport_ice*)tp; 
    685     pj_ice_strans *ice_st = tp_ice->ice_st; 
    686     pj_ice_strans_comp *comp; 
     652    pj_ice_sess_cand cand; 
     653    pj_status_t status; 
    687654 
    688655    pj_bzero(&info->sock_info, sizeof(info->sock_info)); 
    689656    info->sock_info.rtp_sock = info->sock_info.rtcp_sock = PJ_INVALID_SOCKET; 
    690657 
    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); 
    707672    } 
    708673 
     
    760725    if (tp_ice->tx_drop_pct) { 
    761726        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,  
    763728                      "TX RTP packet dropped because of pkt lost " 
    764729                      "simulation")); 
     
    787752{ 
    788753    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) { 
    790755        if (addr == NULL) { 
    791756            addr = &tp_ice->remote_rtcp; 
     
    805770                           unsigned src_addr_len) 
    806771{ 
    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); 
    808775 
    809776    if (comp_id==1 && tp_ice->rtp_cb) { 
     
    812779        if (tp_ice->rx_drop_pct) { 
    813780            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,  
    815782                          "RX RTP packet dropped because of pkt lost " 
    816783                          "simulation")); 
     
    826793    PJ_UNUSED_ARG(src_addr); 
    827794    PJ_UNUSED_ARG(src_addr_len); 
    828  
    829     PJ_TODO(SWITCH_SOURCE_ADDRESS); 
    830795} 
    831796 
    832797 
    833798static void ice_on_ice_complete(pj_ice_strans *ice_st,  
     799                                pj_ice_strans_op op, 
    834800                                pj_status_t result) 
    835801{ 
    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); 
    869805 
    870806    /* Notify application */ 
    871807    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); 
    873809} 
    874810 
     
    902838    if (tp_ice->ice_st) { 
    903839        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); 
    908847    } 
    909848 
Note: See TracChangeset for help on using the changeset viewer.