Ticket #467: ticket467.2.patch

File ticket467.2.patch, 16.3 KB (added by nanang, 16 years ago)
  • pjmedia/include/pjmedia/sdp.h

     
    493493                                           unsigned option); 
    494494 
    495495 
     496/** 
     497 * Compare two media transports for compatibility. 
     498 * 
     499 * @param t1        The first media transport to compare. 
     500 * @param t2        The second media transport to compare. 
     501 * 
     502 * @return          PJ_SUCCESS when both media transports are compatible, 
     503 *                  otherwise returns PJMEDIA_SDP_ETPORTNOTEQUAL. 
     504 */ 
     505PJ_DECL(pj_status_t) pjmedia_sdp_transport_cmp(const pj_str_t *t1, 
     506                                               const pj_str_t *t2); 
    496507 
     508 
     509/** 
     510 * Deactivate SDP media. 
     511 * 
     512 * @param m         The SDP media to deactivate. 
     513 * 
     514 * @return          PJ_SUCCESS when SDP media successfully deactivated, 
     515 *                  otherwise appropriate status code returned. 
     516 */ 
     517PJ_DECL(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool, 
     518                                                  pjmedia_sdp_media *m); 
     519 
     520 
    497521/* ************************************************************************** 
    498522 * SDP SESSION DESCRIPTION 
    499523 **************************************************************************** 
  • pjmedia/src/pjmedia/sdp.c

     
    12811281    return PJ_SUCCESS; 
    12821282} 
    12831283 
     1284PJ_DEF(pj_status_t) pjmedia_sdp_transport_cmp( const pj_str_t *t1, 
     1285                                               const pj_str_t *t2) 
     1286{ 
     1287    static const pj_str_t ID_RTP_AVP  = { "RTP/AVP", 7 }; 
     1288    static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; 
    12841289 
     1290    /* Exactly equal? */ 
     1291    if (pj_stricmp(t1, t2) == 0) 
     1292        return PJ_SUCCESS; 
     1293 
     1294    /* Compatible? */ 
     1295    if ((!pj_stricmp(t1, &ID_RTP_AVP) || !pj_stricmp(t1, &ID_RTP_SAVP)) && 
     1296        (!pj_stricmp(t2, &ID_RTP_AVP) || !pj_stricmp(t2, &ID_RTP_SAVP))) 
     1297        return PJ_SUCCESS; 
     1298 
     1299    return PJMEDIA_SDP_ETPORTNOTEQUAL; 
     1300} 
     1301 
     1302 
     1303PJ_DEF(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool, 
     1304                                                 pjmedia_sdp_media *m) 
     1305{ 
     1306    pjmedia_sdp_attr *attr; 
     1307    static const pj_str_t ID_INACTIVE = { "inactive", 8 }; 
     1308 
     1309    attr = pjmedia_sdp_attr_create(pool, ID_INACTIVE.ptr, NULL); 
     1310    if (NULL == attr) 
     1311        return PJ_ENOMEM; 
     1312 
     1313    m->attr[m->attr_count++] = attr; 
     1314    m->desc.port = 0; 
     1315 
     1316    return PJ_SUCCESS; 
     1317} 
  • pjmedia/include/pjmedia/transport.h

     
    212212 */ 
    213213typedef struct pjmedia_transport pjmedia_transport; 
    214214 
     215/** 
     216 * This enumeration specifies the general behaviour of media processing 
     217 */ 
     218typedef enum pjmedia_tranport_media_option 
     219{ 
     220    /** 
     221     * When this flag is specified, the transport will not perform media 
     222     * transport validation, this is useful when transport is stacked with 
     223     * other transport, for example when transport UDP is stacked under 
     224     * transport SRTP, media transport validation only need to be done by  
     225     * transport SRTP. 
     226     */ 
     227    PJMEDIA_TPMED_NO_TRANSPORT_CHECKING = 1 
    215228 
     229} pjmedia_tranport_media_option; 
     230 
    216231/** 
    217232 * This structure describes the operations for the stream transport. 
    218233 */ 
     
    292307     */ 
    293308    pj_status_t (*media_create)(pjmedia_transport *tp, 
    294309                                pj_pool_t *pool, 
     310                                pjmedia_tranport_media_option option, 
    295311                                pjmedia_sdp_session *sdp_local, 
    296312                                const pjmedia_sdp_session *sdp_remote, 
    297313                                unsigned media_index); 
     
    516532 */ 
    517533PJ_INLINE(pj_status_t) pjmedia_transport_media_create(pjmedia_transport *tp, 
    518534                                    pj_pool_t *pool, 
     535                                    pjmedia_tranport_media_option option, 
    519536                                    pjmedia_sdp_session *sdp_local, 
    520537                                    const pjmedia_sdp_session *sdp_remote, 
    521538                                    unsigned media_index) 
    522539{ 
    523     return (*tp->op->media_create)(tp, pool, sdp_local, sdp_remote,  
     540    return (*tp->op->media_create)(tp, pool, option, sdp_local, sdp_remote,  
    524541                                   media_index); 
    525542} 
    526543 
     
    540557 * 
    541558 * @param tp            The media transport. 
    542559 * @param pool          The memory pool. 
     560 * @param option        The media transport option. 
    543561 * @param sdp_local     Local SDP. 
    544562 * @param sdp_remote    Remote SDP. 
    545563 * @param media_index   Media index to start. 
  • pjmedia/src/pjmedia/transport_udp.c

     
    3535/* Maximum pending write operations */ 
    3636#define MAX_PENDING 4 
    3737 
     38static const pj_str_t ID_RTP_AVP  = { "RTP/AVP", 7 }; 
     39 
    3840/* Pending write buffer */ 
    3941typedef struct pending_write 
    4042{ 
     
    4951 
    5052    pj_pool_t          *pool;           /**< Memory pool                    */ 
    5153    unsigned            options;        /**< Transport options.             */ 
     54    unsigned            media_options;  /**< Transport media options.       */ 
    5255    void               *user_data;      /**< Only valid when attached       */ 
    5356    pj_bool_t           attached;       /**< Has attachment?                */ 
    5457    pj_sockaddr         rem_rtp_addr;   /**< Remote RTP address             */ 
     
    120123                                       pj_size_t size); 
    121124static pj_status_t transport_media_create(pjmedia_transport *tp, 
    122125                                       pj_pool_t *pool, 
     126                                       pjmedia_tranport_media_option option, 
    123127                                       pjmedia_sdp_session *sdp_local, 
    124128                                       const pjmedia_sdp_session *sdp_remote, 
    125129                                       unsigned media_index); 
     
    764768 
    765769static pj_status_t transport_media_create(pjmedia_transport *tp, 
    766770                                  pj_pool_t *pool, 
     771                                  pjmedia_tranport_media_option option, 
    767772                                  pjmedia_sdp_session *sdp_local, 
    768773                                  const pjmedia_sdp_session *sdp_remote, 
    769774                                  unsigned media_index) 
    770775{ 
    771     PJ_UNUSED_ARG(tp); 
    772     PJ_UNUSED_ARG(pool); 
    773     PJ_UNUSED_ARG(sdp_local); 
    774     PJ_UNUSED_ARG(sdp_remote); 
    775     PJ_UNUSED_ARG(media_index); 
     776    struct transport_udp *udp = (struct transport_udp*)tp; 
    776777 
     778    PJ_ASSERT_RETURN(tp && pool && sdp_local, PJ_EINVAL); 
     779    udp->media_options = option; 
     780 
     781    /* Validate media transport */ 
     782    /* By now, this transport only support RTP/AVP transport */ 
     783    if ((udp->media_options & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) { 
     784        pjmedia_sdp_media *m_rem, *m_loc; 
     785 
     786        m_rem = sdp_remote? sdp_remote->media[media_index] : NULL; 
     787        m_loc = sdp_local->media[media_index]; 
     788 
     789        if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) || 
     790           (m_rem && pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP))) 
     791        { 
     792            pjmedia_sdp_media_deactivate(pool, m_loc); 
     793            return PJMEDIA_SDP_EINPROTO; 
     794        } 
     795    } 
     796 
    777797    return PJ_SUCCESS; 
    778798} 
    779799 
     
    783803                                  const pjmedia_sdp_session *sdp_remote, 
    784804                                  unsigned media_index) 
    785805{ 
    786     PJ_UNUSED_ARG(tp); 
    787     PJ_UNUSED_ARG(pool); 
    788     PJ_UNUSED_ARG(sdp_local); 
    789     PJ_UNUSED_ARG(sdp_remote); 
    790     PJ_UNUSED_ARG(media_index); 
     806    struct transport_udp *udp = (struct transport_udp*)tp; 
    791807 
     808    PJ_ASSERT_RETURN(tp && pool && sdp_local, PJ_EINVAL); 
     809 
     810    /* Validate media transport */ 
     811    /* By now, this transport only support RTP/AVP transport */ 
     812    if ((udp->media_options & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) { 
     813        pjmedia_sdp_media *m_rem, *m_loc; 
     814 
     815        m_rem = sdp_remote->media[media_index]; 
     816        m_loc = sdp_local->media[media_index]; 
     817 
     818        if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) || 
     819            pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP)) 
     820        { 
     821            pjmedia_sdp_media_deactivate(pool, m_loc); 
     822            return PJMEDIA_SDP_EINPROTO; 
     823        } 
     824    } 
     825 
    792826    return PJ_SUCCESS; 
    793827} 
    794828 
  • pjmedia/src/pjmedia/transport_ice.c

     
    2424 
    2525#define THIS_FILE   "transport_ice.c" 
    2626 
     27static const pj_str_t ID_RTP_AVP  = { "RTP/AVP", 7 }; 
     28 
    2729struct transport_ice 
    2830{ 
    2931    pjmedia_transport    base; 
    3032    pj_ice_strans       *ice_st; 
    3133    pjmedia_ice_cb       cb; 
     34    unsigned             media_option; 
    3235 
    3336    pj_time_val          start_ice; 
    3437     
     
    7477                                       pj_size_t size); 
    7578static pj_status_t transport_media_create(pjmedia_transport *tp, 
    7679                                       pj_pool_t *pool, 
     80                                       pjmedia_tranport_media_option option, 
    7781                                       pjmedia_sdp_session *sdp_local, 
    7882                                       const pjmedia_sdp_session *sdp_remote, 
    7983                                       unsigned media_index); 
     
    258262 */ 
    259263static pj_status_t transport_media_create(pjmedia_transport *tp, 
    260264                                       pj_pool_t *pool, 
     265                                       pjmedia_tranport_media_option option, 
    261266                                       pjmedia_sdp_session *sdp_local, 
    262267                                       const pjmedia_sdp_session *sdp_remote, 
    263268                                       unsigned media_index) 
     
    270275    unsigned i, cand_cnt; 
    271276    pj_status_t status; 
    272277 
     278    tp_ice->media_option = option; 
     279 
     280    /* Validate media transport */ 
     281    /* By now, this transport only support RTP/AVP transport */ 
     282    if ((tp_ice->media_option & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) { 
     283        pjmedia_sdp_media *m_rem, *m_loc; 
     284 
     285        m_rem = sdp_remote? sdp_remote->media[media_index] : NULL; 
     286        m_loc = sdp_local->media[media_index]; 
     287 
     288        if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) || 
     289           (m_rem && pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP))) 
     290        { 
     291            pjmedia_sdp_media_deactivate(pool, m_loc); 
     292            return PJMEDIA_SDP_EINPROTO; 
     293        } 
     294    } 
     295 
    273296    /* Init ICE */ 
    274297    ice_role = (sdp_remote==NULL ? PJ_ICE_SESS_ROLE_CONTROLLING :  
    275298                                   PJ_ICE_SESS_ROLE_CONTROLLED); 
     
    499522    pj_str_t uname, pass; 
    500523    pj_status_t status; 
    501524 
    502     PJ_UNUSED_ARG(sdp_local); 
    503  
    504525    PJ_ASSERT_RETURN(tp && pool && sdp_remote, PJ_EINVAL); 
    505526    PJ_ASSERT_RETURN(media_index < sdp_remote->media_count, PJ_EINVAL); 
    506527 
    507528    sdp_med = sdp_remote->media[media_index]; 
    508529 
     530    /* Validate media transport */ 
     531    /* By now, this transport only support RTP/AVP transport */ 
     532    if ((tp_ice->media_option & PJMEDIA_TPMED_NO_TRANSPORT_CHECKING) == 0) { 
     533        pjmedia_sdp_media *m_rem, *m_loc; 
     534 
     535        m_rem = sdp_remote->media[media_index]; 
     536        m_loc = sdp_local->media[media_index]; 
     537 
     538        if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) || 
     539           (pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP))) 
     540        { 
     541            pjmedia_sdp_media_deactivate(pool, m_loc); 
     542            return PJMEDIA_SDP_EINPROTO; 
     543        } 
     544    } 
     545 
    509546    /* Get the SDP connection for the media stream. 
    510547     * We'll verify later if the SDP connection address is specified  
    511548     * as one of the candidate. 
  • pjmedia/src/pjmedia/transport_srtp.c

     
    3535/* Maximum size of packet */ 
    3636#define MAX_BUFFER_LEN  1500 
    3737#define MAX_KEY_LEN     32 
    38 #define DEACTIVATE_MEDIA(pool, m) {\ 
    39             attr = pjmedia_sdp_attr_create(pool, ID_INACTIVE.ptr, NULL); \ 
    40             m->attr[m->attr_count++] = attr; \ 
    41             m->desc.port = 0; \ 
    42         } 
     38#define DEACTIVATE_MEDIA(pool, m) pjmedia_sdp_media_deactivate(pool, m) 
    4339 
    4440static const pj_str_t ID_RTP_AVP  = { "RTP/AVP", 7 }; 
    4541static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; 
     
    8379    pj_pool_t           *pool; 
    8480    pj_lock_t           *mutex; 
    8581    char                 tx_buffer[MAX_BUFFER_LEN]; 
     82    pjmedia_srtp_setting setting; 
     83    unsigned             media_option; 
    8684 
    87     pjmedia_srtp_setting setting; 
    8885    /* SRTP policy */ 
    8986    pj_bool_t            session_inited; 
    9087    pj_bool_t            offerer_side; 
     
    150147                                       pj_size_t size); 
    151148static pj_status_t transport_media_create(pjmedia_transport *tp, 
    152149                                       pj_pool_t *pool, 
     150                                       pjmedia_tranport_media_option option, 
    153151                                       pjmedia_sdp_session *sdp_local, 
    154152                                       const pjmedia_sdp_session *sdp_remote, 
    155153                                       unsigned media_index); 
     
    924922 
    925923static pj_status_t transport_media_create(pjmedia_transport *tp, 
    926924                                          pj_pool_t *pool, 
     925                                          pjmedia_tranport_media_option option, 
    927926                                          pjmedia_sdp_session *sdp_local, 
    928927                                          const pjmedia_sdp_session *sdp_remote, 
    929928                                          unsigned media_index) 
     
    937936    pjmedia_sdp_attr *attr; 
    938937    pj_str_t attr_value; 
    939938    int i, j; 
     939    unsigned member_tp_option; 
    940940 
    941941    PJ_ASSERT_RETURN(tp && pool && sdp_local, PJ_EINVAL); 
     942     
     943    srtp->media_option = option; 
     944    member_tp_option = option | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 
    942945 
    943946    pj_bzero(&srtp->rx_policy, sizeof(srtp->tx_policy)); 
    944947    pj_bzero(&srtp->tx_policy, sizeof(srtp->rx_policy)); 
     
    11301133 
    11311134BYPASS_SRTP: 
    11321135    srtp->bypass_srtp = PJ_TRUE; 
     1136    member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 
    11331137 
    11341138PROPAGATE_MEDIA_CREATE: 
    1135     return pjmedia_transport_media_create(srtp->real_tp, pool, sdp_local,  
    1136                                            sdp_remote, media_index); 
     1139    return pjmedia_transport_media_create(srtp->real_tp, pool,  
     1140                            member_tp_option, 
     1141                            sdp_local, sdp_remote, media_index); 
    11371142} 
    11381143 
    11391144 
     
    11471152    struct transport_srtp *srtp = (struct transport_srtp*) tp; 
    11481153    pjmedia_sdp_media *m_rem, *m_loc; 
    11491154    pj_status_t status; 
    1150     pjmedia_sdp_attr *attr; 
    11511155    int i; 
    11521156 
    11531157    PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL); 
     
    11711175            } 
    11721176            goto BYPASS_SRTP; 
    11731177        } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
    1174             if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) { 
    1175                 DEACTIVATE_MEDIA(pool, m_loc); 
    1176                 return PJMEDIA_SDP_EINPROTO; 
    1177             } 
     1178            // Regardless the answer's transport type (RTP/AVP or RTP/SAVP), 
     1179            // the answer must be processed through in optional mode. 
     1180            // Please note that at this point transport type is ensured to be  
     1181            // RTP/AVP or RTP/SAVP, see transport_media_create() 
     1182            //if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) { 
     1183                //DEACTIVATE_MEDIA(pool, m_loc); 
     1184                //return PJMEDIA_SDP_EINPROTO; 
     1185            //} 
    11781186        } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    11791187            if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) { 
    11801188                DEACTIVATE_MEDIA(pool, m_loc); 
  • pjmedia/src/pjmedia/sdp_neg.c

     
    479479    } 
    480480 
    481481 
    482     /* Chec that transport in the answer match our offer. */ 
     482    /* Check that transport in the answer match our offer. */ 
    483483 
    484     if (pj_strcmp(&answer->desc.transport,  
    485                   &offer->desc.transport)!=0)  
     484    /* At this point, transport type must be compatible,  
     485     * the transport instance will do more validation later. 
     486     */ 
     487    if (pjmedia_sdp_transport_cmp(&answer->desc.transport,  
     488                                  &offer->desc.transport)  
     489        != PJ_SUCCESS) 
    486490    { 
    487         /* The transport in the answer is different than the offer! */ 
    488491        return PJMEDIA_SDPNEG_EINVANSTP; 
    489492    } 
    490493 
     494 
    491495    /* Check if remote has rejected our offer */ 
    492496     
    493497    if (answer->desc.port == 0) { 
  • pjmedia/src/pjmedia/session.c

     
    190190 
    191191    /* Transport protocol */ 
    192192 
    193     /* Transport type must be equal */ 
    194     if (pj_stricmp(&rem_m->desc.transport,  
    195                    &local_m->desc.transport) != 0)  
    196     { 
    197         si->type = PJMEDIA_TYPE_UNKNOWN; 
     193    /* At this point, transport type must be compatible,  
     194     * the transport instance will do more validation later. 
     195     */ 
     196    status = pjmedia_sdp_transport_cmp(&rem_m->desc.transport,  
     197                                       &local_m->desc.transport); 
     198    if (status != PJ_SUCCESS) 
    198199        return PJMEDIA_SDPNEG_EINVANSTP; 
    199     } 
    200200 
    201201    if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) { 
    202202 
  • pjsip/src/pjsua-lib/pjsua_media.c

     
    859859    } 
    860860 
    861861    /* Give the SDP to media transport */ 
    862     status = pjmedia_transport_media_create(call->med_tp, pool,  
     862    status = pjmedia_transport_media_create(call->med_tp, pool, 0, 
    863863                                            sdp, rem_sdp, MEDIA_IDX); 
    864864    if (status != PJ_SUCCESS) { 
    865865        if (sip_status_code) *sip_status_code = PJSIP_SC_NOT_ACCEPTABLE; 
  • pjsip/src/pjsua-lib/pjsua_call.c

     
    24842484        if (inv->state != PJSIP_INV_STATE_NULL && 
    24852485            inv->state != PJSIP_INV_STATE_CONFIRMED)  
    24862486        { 
    2487             //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); 
     2487            call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); 
    24882488        } 
    24892489 
    24902490        PJSUA_UNLOCK();