Ignore:
Timestamp:
Jun 19, 2008 2:10:28 PM (16 years ago)
Author:
bennylp
Message:

Ticket #549: major modification in media transport API to support more offer/answer scenarios

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c

    r2015 r2032  
    9292    pjmedia_srtp_crypto  rx_policy; 
    9393 
     94    /* Temporary policy for negotiation */ 
     95    pjmedia_srtp_crypto  tx_policy_neg; 
     96    pjmedia_srtp_crypto  rx_policy_neg; 
     97 
    9498    /* libSRTP contexts */ 
    9599    srtp_t               srtp_tx_ctx; 
     
    106110         
    107111    /* Transport information */ 
    108     pjmedia_transport   *real_tp; /**< Underlying transport.       */ 
     112    pjmedia_transport   *member_tp; /**< Underlying transport.       */ 
     113 
     114    /* When in SRTP optional mode, instead of always offering RTP/AVP, 
     115     * we should create offer based on remote preference. At the first time, 
     116     * remote preference is unknown, it is known after media_start() called. 
     117     * So next time the same session need to create an offer, it will create 
     118     * SDP with transport type based on remote preference. 
     119     */ 
     120    pj_bool_t            remote_prefer_rtp_savp; 
    109121 
    110122} transport_srtp; 
     
    152164                                       pj_size_t size); 
    153165static pj_status_t transport_media_create(pjmedia_transport *tp, 
    154                                        pj_pool_t *pool, 
     166                                       pj_pool_t *sdp_pool, 
    155167                                       unsigned options, 
     168                                       const pjmedia_sdp_session *sdp_remote, 
     169                                       unsigned media_index); 
     170static pj_status_t transport_encode_sdp(pjmedia_transport *tp, 
     171                                       pj_pool_t *sdp_pool, 
    156172                                       pjmedia_sdp_session *sdp_local, 
    157173                                       const pjmedia_sdp_session *sdp_remote, 
     
    159175static pj_status_t transport_media_start (pjmedia_transport *tp, 
    160176                                       pj_pool_t *pool, 
    161                                        pjmedia_sdp_session *sdp_local, 
     177                                       const pjmedia_sdp_session *sdp_local, 
    162178                                       const pjmedia_sdp_session *sdp_remote, 
    163179                                       unsigned media_index); 
     
    179195    &transport_send_rtcp2, 
    180196    &transport_media_create, 
     197    &transport_encode_sdp, 
    181198    &transport_media_start, 
    182199    &transport_media_stop, 
     
    332349    srtp->session_inited = PJ_FALSE; 
    333350    srtp->bypass_srtp = PJ_FALSE; 
     351    srtp->remote_prefer_rtp_savp = PJ_FALSE; 
    334352 
    335353    if (opt) { 
     
    368386 
    369387    /* Set underlying transport */ 
    370     srtp->real_tp = tp; 
     388    srtp->member_tp = tp; 
    371389 
    372390    /* Done */ 
     
    458476    srtp->tx_policy = *tx; 
    459477    pj_strset(&srtp->tx_policy.key,  srtp->tx_key, tx->key.slen); 
    460     srtp->tx_policy.name =  
    461                         pj_str(crypto_suites[get_crypto_idx(&tx->name)].name); 
     478    srtp->tx_policy.name=pj_str(crypto_suites[get_crypto_idx(&tx->name)].name); 
    462479 
    463480 
     
    492509    srtp->rx_policy = *rx; 
    493510    pj_strset(&srtp->rx_policy.key,  srtp->rx_key, rx->key.slen); 
    494     srtp->rx_policy.name =  
    495                         pj_str(crypto_suites[get_crypto_idx(&rx->name)].name); 
     511    srtp->rx_policy.name=pj_str(crypto_suites[get_crypto_idx(&rx->name)].name); 
    496512 
    497513    /* Declare SRTP session initialized */ 
     
    551567    PJ_ASSERT_RETURN(tp, NULL); 
    552568 
    553     return srtp->real_tp; 
     569    return srtp->member_tp; 
    554570} 
    555571 
     
    578594              sizeof(srtp_info)); 
    579595 
    580     return pjmedia_transport_get_info(srtp->real_tp, info); 
     596    return pjmedia_transport_get_info(srtp->member_tp, info); 
    581597} 
    582598 
     
    595611 
    596612    /* Attach itself to transport */ 
    597     status = pjmedia_transport_attach(srtp->real_tp, srtp, rem_addr, rem_rtcp, 
     613    status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr, rem_rtcp, 
    598614                                      addr_len, &srtp_rtp_cb, &srtp_rtcp_cb); 
    599615    if (status != PJ_SUCCESS) 
     
    615631    PJ_ASSERT_ON_FAIL(tp, return); 
    616632 
    617     if (srtp->real_tp) { 
    618         pjmedia_transport_detach(srtp->real_tp, srtp); 
     633    if (srtp->member_tp) { 
     634        pjmedia_transport_detach(srtp->member_tp, srtp); 
    619635    } 
    620636 
     
    635651 
    636652    if (srtp->bypass_srtp) 
    637         return pjmedia_transport_send_rtp(srtp->real_tp, pkt, size); 
     653        return pjmedia_transport_send_rtp(srtp->member_tp, pkt, size); 
    638654 
    639655    if (!srtp->session_inited) 
     
    648664    err = srtp_protect(srtp->srtp_tx_ctx, srtp->tx_buffer, &len); 
    649665    if (err == err_status_ok) { 
    650         status = pjmedia_transport_send_rtp(srtp->real_tp, srtp->tx_buffer, len); 
     666        status = pjmedia_transport_send_rtp(srtp->member_tp, srtp->tx_buffer, len); 
    651667    } else { 
    652668        status = PJMEDIA_ERRNO_FROM_LIBSRTP(err); 
     
    677693 
    678694    if (srtp->bypass_srtp) { 
    679         return pjmedia_transport_send_rtcp2(srtp->real_tp, addr, addr_len,  
     695        return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,  
    680696                                            pkt, size); 
    681697    } 
     
    693709     
    694710    if (err == err_status_ok) { 
    695         status = pjmedia_transport_send_rtcp2(srtp->real_tp, addr, addr_len, 
     711        status = pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len, 
    696712                                              srtp->tx_buffer, len); 
    697713    } else { 
     
    711727    transport_srtp *srtp = (transport_srtp *) tp; 
    712728 
    713     return pjmedia_transport_simulate_lost(srtp->real_tp, dir, pct_lost); 
     729    return pjmedia_transport_simulate_lost(srtp->member_tp, dir, pct_lost); 
    714730} 
    715731 
     
    723739    pjmedia_transport_detach(tp, NULL); 
    724740     
    725     if (srtp->setting.close_member_tp && srtp->real_tp) { 
    726         pjmedia_transport_close(srtp->real_tp); 
     741    if (srtp->setting.close_member_tp && srtp->member_tp) { 
     742        pjmedia_transport_close(srtp->member_tp); 
    727743    } 
    728744 
     
    956972 
    957973static pj_status_t transport_media_create(pjmedia_transport *tp, 
    958                                           pj_pool_t *pool, 
     974                                          pj_pool_t *sdp_pool, 
    959975                                          unsigned options, 
    960                                           pjmedia_sdp_session *sdp_local, 
    961976                                          const pjmedia_sdp_session *sdp_remote, 
    962977                                          unsigned media_index) 
     978{ 
     979    struct transport_srtp *srtp = (struct transport_srtp*) tp; 
     980    unsigned member_tp_option; 
     981 
     982    PJ_ASSERT_RETURN(tp, PJ_EINVAL); 
     983     
     984    pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg)); 
     985    pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg)); 
     986 
     987    srtp->media_option = options; 
     988    member_tp_option = options | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 
     989 
     990    srtp->offerer_side = sdp_remote == NULL; 
     991 
     992    /* Validations */ 
     993    if (srtp->offerer_side) { 
     994 
     995        if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) 
     996            goto BYPASS_SRTP; 
     997 
     998    } else { 
     999 
     1000        pjmedia_sdp_media *m_rem; 
     1001         
     1002        m_rem = sdp_remote->media[media_index]; 
     1003 
     1004        /* Nothing to do on inactive media stream */ 
     1005        if (pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)) 
     1006            goto BYPASS_SRTP; 
     1007 
     1008        /* Validate remote media transport based on SRTP usage option. 
     1009         */ 
     1010        switch (srtp->setting.use) { 
     1011            case PJMEDIA_SRTP_DISABLED: 
     1012                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 
     1013                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     1014                goto BYPASS_SRTP; 
     1015            case PJMEDIA_SRTP_OPTIONAL: 
     1016                break; 
     1017            case PJMEDIA_SRTP_MANDATORY: 
     1018                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) 
     1019                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     1020                break; 
     1021        } 
     1022 
     1023    } 
     1024    goto PROPAGATE_MEDIA_CREATE; 
     1025 
     1026BYPASS_SRTP: 
     1027    srtp->bypass_srtp = PJ_TRUE; 
     1028    member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 
     1029 
     1030PROPAGATE_MEDIA_CREATE: 
     1031    return pjmedia_transport_media_create(srtp->member_tp, sdp_pool,  
     1032                                          member_tp_option, sdp_remote, 
     1033                                          media_index); 
     1034} 
     1035 
     1036static pj_status_t transport_encode_sdp(pjmedia_transport *tp, 
     1037                                        pj_pool_t *sdp_pool, 
     1038                                        pjmedia_sdp_session *sdp_local, 
     1039                                        const pjmedia_sdp_session *sdp_remote, 
     1040                                        unsigned media_index) 
    9631041{ 
    9641042    struct transport_srtp *srtp = (struct transport_srtp*) tp; 
     
    9711049    pj_str_t attr_value; 
    9721050    unsigned i, j; 
    973     unsigned member_tp_option; 
    974  
    975     PJ_ASSERT_RETURN(tp && pool && sdp_local, PJ_EINVAL); 
     1051 
     1052    PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL); 
    9761053     
    977     srtp->media_option = options; 
    978     member_tp_option = options | PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 
    979  
    980     pj_bzero(&srtp->rx_policy, sizeof(srtp->tx_policy)); 
    981     pj_bzero(&srtp->tx_policy, sizeof(srtp->rx_policy)); 
     1054    srtp->offerer_side = sdp_remote == NULL; 
    9821055 
    9831056    m_rem = sdp_remote ? sdp_remote->media[media_index] : NULL; 
    9841057    m_loc = sdp_local->media[media_index]; 
    9851058 
    986     /* bypass if media transport is not RTP/AVP or RTP/SAVP */ 
     1059    /* Bypass if media transport is not RTP/AVP or RTP/SAVP */ 
    9871060    if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP)  != 0 &&  
    9881061        pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0) 
     
    9921065    if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) ||  
    9931066        (m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL))) 
    994     { 
    9951067        goto BYPASS_SRTP; 
    996     } 
    997  
    998     srtp->offerer_side = !sdp_remote; 
    9991068 
    10001069    /* Check remote media transport & set local media transport  
     
    10021071     */ 
    10031072    if (srtp->offerer_side) { 
    1004         if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    1005             goto BYPASS_SRTP; 
    1006         } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
    1007             m_loc->desc.transport = ID_RTP_AVP; 
    1008         } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    1009             m_loc->desc.transport = ID_RTP_SAVP; 
     1073 
     1074        /* Generate transport */ 
     1075        switch (srtp->setting.use) { 
     1076            case PJMEDIA_SRTP_DISABLED: 
     1077                goto BYPASS_SRTP; 
     1078            case PJMEDIA_SRTP_OPTIONAL: 
     1079                m_loc->desc.transport = srtp->remote_prefer_rtp_savp? 
     1080                                        ID_RTP_SAVP : ID_RTP_AVP; 
     1081                break; 
     1082            case PJMEDIA_SRTP_MANDATORY: 
     1083                m_loc->desc.transport = ID_RTP_SAVP; 
     1084                break; 
    10101085        } 
     1086 
     1087        /* Generate crypto attribute if not yet */ 
     1088        if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) { 
     1089            for (i=0; i<srtp->setting.crypto_count; ++i) { 
     1090                /* Offer crypto-suites based on setting. */ 
     1091                buffer_len = MAXLEN; 
     1092                status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len, 
     1093                                                    &srtp->setting.crypto[i], 
     1094                                                    i+1); 
     1095                if (status != PJ_SUCCESS) 
     1096                    return status; 
     1097 
     1098                /* If buffer_len==0, just skip the crypto attribute. */ 
     1099                if (buffer_len) { 
     1100                    pj_strset(&attr_value, buffer, buffer_len); 
     1101                    attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,  
     1102                                                   &attr_value); 
     1103                    m_loc->attr[m_loc->attr_count++] = attr; 
     1104                } 
     1105            } 
     1106        } 
     1107 
    10111108    } else { 
    1012         if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    1013             if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) { 
    1014                 DEACTIVATE_MEDIA(pool, m_loc); 
    1015                 return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     1109        /* Answerer side */ 
     1110 
     1111        pj_assert(sdp_remote && m_rem); 
     1112 
     1113        /* Generate transport */ 
     1114        switch (srtp->setting.use) { 
     1115            case PJMEDIA_SRTP_DISABLED: 
     1116                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) == 0) 
     1117                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     1118                goto BYPASS_SRTP; 
     1119            case PJMEDIA_SRTP_OPTIONAL: 
     1120                m_loc->desc.transport = m_rem->desc.transport; 
     1121                break; 
     1122            case PJMEDIA_SRTP_MANDATORY: 
     1123                if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) 
     1124                    return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     1125                m_loc->desc.transport = ID_RTP_SAVP; 
     1126                break; 
     1127        } 
     1128 
     1129        /* Generate crypto attribute if not yet */ 
     1130        if (pjmedia_sdp_media_find_attr(m_loc, &ID_CRYPTO, NULL) == NULL) { 
     1131 
     1132            pjmedia_srtp_crypto tmp_rx_crypto; 
     1133            pj_bool_t has_crypto_attr = PJ_FALSE; 
     1134            int matched_idx = -1; 
     1135            int chosen_tag = 0; 
     1136            int tags[64]; /* assume no more than 64 crypto attrs in a media */ 
     1137            int cr_attr_count = 0; 
     1138 
     1139            /* Find supported crypto-suite, get the tag, and assign policy_local */ 
     1140            for (i=0; i<m_rem->attr_count; ++i) { 
     1141                if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 
     1142                    continue; 
     1143 
     1144                has_crypto_attr = PJ_TRUE; 
     1145 
     1146                status = parse_attr_crypto(srtp->pool, m_rem->attr[i],  
     1147                                           &tmp_rx_crypto, &tags[cr_attr_count]); 
     1148                if (status != PJ_SUCCESS) 
     1149                    return status; 
     1150          
     1151                /* Check duplicated tag */ 
     1152                for (j=0; j<cr_attr_count; ++j) { 
     1153                    if (tags[j] == tags[cr_attr_count]) { 
     1154                        DEACTIVATE_MEDIA(sdp_pool, m_loc); 
     1155                        return PJMEDIA_SRTP_ESDPDUPCRYPTOTAG; 
     1156                    } 
     1157                } 
     1158 
     1159                if (matched_idx == -1) { 
     1160                    /* lets see if the crypto-suite offered is supported */ 
     1161                    for (j=0; j<srtp->setting.crypto_count; ++j) 
     1162                        if (pj_stricmp(&tmp_rx_crypto.name,  
     1163                                       &srtp->setting.crypto[j].name) == 0) 
     1164                        { 
     1165                            int cs_idx = get_crypto_idx(&tmp_rx_crypto.name); 
     1166 
     1167                            /* Force to use test key */ 
     1168                            /* bad keys for snom: */ 
     1169                            //char *hex_test_key = "58b29c5c8f42308120ce857e439f2d" 
     1170                            //               "7810a8b10ad0b1446be5470faea496"; 
     1171                            //char *hex_test_key = "20a26aac7ba062d356ff52b61e3993" 
     1172                            //               "ccb78078f12c64db94b9c294927fd0"; 
     1173                            //pj_str_t *test_key = &srtp->setting.crypto[j].key; 
     1174                            //char  *raw_test_key = pj_pool_zalloc(srtp->pool, 64); 
     1175                            //hex_string_to_octet_string( 
     1176                            //          raw_test_key, 
     1177                            //          hex_test_key, 
     1178                            //          strlen(hex_test_key)); 
     1179                            //pj_strset(test_key, raw_test_key,  
     1180                            //    crypto_suites[cs_idx].cipher_key_len); 
     1181                            /* EO Force to use test key */ 
     1182 
     1183                            if (tmp_rx_crypto.key.slen !=  
     1184                                (int)crypto_suites[cs_idx].cipher_key_len) 
     1185                                return PJMEDIA_SRTP_EINKEYLEN; 
     1186 
     1187                            srtp->rx_policy_neg = tmp_rx_crypto; 
     1188                            chosen_tag = tags[cr_attr_count]; 
     1189                            matched_idx = j; 
     1190                            break; 
     1191                        } 
     1192                } 
     1193                cr_attr_count++; 
    10161194            } 
    1017             goto BYPASS_SRTP; 
    1018         } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
    1019                 m_loc->desc.transport = m_rem->desc.transport; 
    1020         } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    1021             if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP) != 0) { 
    1022                 DEACTIVATE_MEDIA(pool, m_loc); 
    1023                 return PJMEDIA_SRTP_ESDPINTRANSPORT; 
     1195 
     1196            /* Check crypto negotiation result */ 
     1197            switch (srtp->setting.use) { 
     1198                case PJMEDIA_SRTP_DISABLED: 
     1199                    pj_assert(!"Should never reach here"); 
     1200                    break; 
     1201 
     1202                case PJMEDIA_SRTP_OPTIONAL: 
     1203                    /* bypass SRTP when no crypto-attr and remote uses RTP/AVP */ 
     1204                    if (!has_crypto_attr &&  
     1205                        pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 
     1206                        goto BYPASS_SRTP; 
     1207                    /* bypass SRTP when nothing match and remote uses RTP/AVP */ 
     1208                    else if (matched_idx == -1 &&  
     1209                        pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 
     1210                        goto BYPASS_SRTP; 
     1211                    break; 
     1212 
     1213                case PJMEDIA_SRTP_MANDATORY: 
     1214                    /* Do nothing, intentional */ 
     1215                    break; 
    10241216            } 
    1025             m_loc->desc.transport = ID_RTP_SAVP; 
    1026         } 
    1027     } 
    1028  
    1029     /* Generate crypto attribute */ 
    1030     if (srtp->offerer_side) { 
    1031         for (i=0; i<srtp->setting.crypto_count; ++i) { 
    1032             /* Offer crypto-suites based on setting. */ 
     1217 
     1218            /* No crypto attr */ 
     1219            if (!has_crypto_attr) { 
     1220                DEACTIVATE_MEDIA(sdp_pool, m_loc); 
     1221                return PJMEDIA_SRTP_ESDPREQCRYPTO; 
     1222            } 
     1223 
     1224            /* No crypto match */ 
     1225            if (matched_idx == -1) { 
     1226                DEACTIVATE_MEDIA(sdp_pool, m_loc); 
     1227                return PJMEDIA_SRTP_ENOTSUPCRYPTO; 
     1228            } 
     1229 
     1230            /* we have to generate crypto answer,  
     1231             * with srtp->tx_policy_neg matched the offer 
     1232             * and rem_tag contains matched offer tag. 
     1233             */ 
    10331234            buffer_len = MAXLEN; 
    10341235            status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len, 
    1035                                                 &srtp->setting.crypto[i], 
    1036                                                 i+1); 
     1236                                                &srtp->setting.crypto[matched_idx], 
     1237                                                chosen_tag); 
    10371238            if (status != PJ_SUCCESS) 
    10381239                return status; 
    10391240 
     1241            srtp->tx_policy_neg = srtp->setting.crypto[matched_idx]; 
     1242             
    10401243            /* If buffer_len==0, just skip the crypto attribute. */ 
    10411244            if (buffer_len) { 
    10421245                pj_strset(&attr_value, buffer, buffer_len); 
    1043                 attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,  
     1246                attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr,  
    10441247                                               &attr_value); 
    10451248                m_loc->attr[m_loc->attr_count++] = attr; 
    10461249            } 
     1250 
     1251            /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 
    10471252        } 
    1048     } else { 
    1049         /* find supported crypto-suite, get the tag, and assign policy_local */ 
    1050         pjmedia_srtp_crypto tmp_rx_crypto; 
    1051         pj_bool_t has_crypto_attr = PJ_FALSE; 
    1052         pj_bool_t has_match = PJ_FALSE; 
    1053         int chosen_tag = 0; 
    1054         int tags[64]; /* assume no more than 64 crypto attrs in a media */ 
    1055         int cr_attr_count = 0; 
    1056         int k; 
    1057  
    1058         for (i=0; i<m_rem->attr_count; ++i) { 
    1059             if (pj_stricmp(&m_rem->attr[i]->name, &ID_CRYPTO) != 0) 
    1060                 continue; 
    1061  
    1062             has_crypto_attr = PJ_TRUE; 
    1063  
    1064             status = parse_attr_crypto(srtp->pool, m_rem->attr[i],  
    1065                                        &tmp_rx_crypto, &tags[cr_attr_count]); 
    1066             if (status != PJ_SUCCESS) 
    1067                 return status; 
    1068           
    1069             /* Check duplicated tag */ 
    1070             for (k=0; k<cr_attr_count; ++k) { 
    1071                 if (tags[k] == tags[cr_attr_count]) { 
    1072                     DEACTIVATE_MEDIA(pool, m_loc); 
    1073                     return PJMEDIA_SRTP_ESDPDUPCRYPTOTAG; 
    1074                 } 
    1075             } 
    1076  
    1077             if (!has_match) { 
    1078                 /* lets see if the crypto-suite offered is supported */ 
    1079                 for (j=0; j<srtp->setting.crypto_count; ++j) 
    1080                     if (pj_stricmp(&tmp_rx_crypto.name,  
    1081                                    &srtp->setting.crypto[j].name) == 0) 
    1082                     { 
    1083                         int cs_idx = get_crypto_idx(&tmp_rx_crypto.name); 
    1084  
    1085                         /* Force to use test key */ 
    1086                         /* bad keys for snom: */ 
    1087                         //char *hex_test_key = "58b29c5c8f42308120ce857e439f2d" 
    1088                         //                   "7810a8b10ad0b1446be5470faea496"; 
    1089                         //char *hex_test_key = "20a26aac7ba062d356ff52b61e3993" 
    1090                         //                   "ccb78078f12c64db94b9c294927fd0"; 
    1091                         //pj_str_t *test_key = &srtp->setting.crypto[j].key; 
    1092                         //char  *raw_test_key = pj_pool_zalloc(srtp->pool, 64); 
    1093                         //hex_string_to_octet_string( 
    1094                         //              raw_test_key, 
    1095                         //              hex_test_key, 
    1096                         //              strlen(hex_test_key)); 
    1097                         //pj_strset(test_key, raw_test_key,  
    1098                         //        crypto_suites[cs_idx].cipher_key_len); 
    1099                         /* EO Force to use test key */ 
    1100  
    1101                         if (tmp_rx_crypto.key.slen !=  
    1102                             (int)crypto_suites[cs_idx].cipher_key_len) 
    1103                             return PJMEDIA_SRTP_EINKEYLEN; 
    1104  
    1105                         srtp->tx_policy = srtp->setting.crypto[j]; 
    1106                         srtp->rx_policy = tmp_rx_crypto; 
    1107                         chosen_tag = tags[cr_attr_count]; 
    1108                         has_match = PJ_TRUE; 
    1109                         break; 
    1110                     } 
    1111             } 
    1112             cr_attr_count++; 
    1113         } 
    1114  
    1115         if (srtp->setting.use == PJMEDIA_SRTP_DISABLED) { 
    1116             /* bypass when remote uses RTP/AVP and we disable SRTP */ 
    1117             goto BYPASS_SRTP; 
    1118         } else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) { 
    1119             /* bypass SRTP when no crypto-attr but remote uses RTP/AVP */ 
    1120             if (!has_crypto_attr &&  
    1121                 pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 
    1122                 goto BYPASS_SRTP; 
    1123             /* bypass SRTP when nothing match but remote uses RTP/AVP */ 
    1124             if (!has_match &&  
    1125                 pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0) 
    1126                 goto BYPASS_SRTP; 
    1127         } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 
    1128             /* do nothing, this is intended */ 
    1129         } 
    1130  
    1131         /* No crypto attr */ 
    1132         if (!has_crypto_attr) { 
    1133             DEACTIVATE_MEDIA(pool, m_loc); 
    1134             return PJMEDIA_SRTP_ESDPREQCRYPTO; 
    1135         } 
    1136  
    1137         /* No crypto match */ 
    1138         if (!has_match) { 
    1139             DEACTIVATE_MEDIA(pool, m_loc); 
    1140             return PJMEDIA_SRTP_ENOTSUPCRYPTO; 
    1141         } 
    1142  
    1143         /* we have to generate crypto answer,  
    1144          * with srtp->tx_policy matched the offer 
    1145          * and rem_tag contains matched offer tag. 
    1146          */ 
    1147         buffer_len = MAXLEN; 
    1148         status = generate_crypto_attr_value(srtp->pool, buffer, &buffer_len, 
    1149                                             &srtp->tx_policy, 
    1150                                             chosen_tag); 
    1151         if (status != PJ_SUCCESS) 
    1152             return status; 
    1153  
    1154         /* If buffer_len==0, just skip the crypto attribute. */ 
    1155         if (buffer_len) { 
    1156             pj_strset(&attr_value, buffer, buffer_len); 
    1157             attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,  
    1158                                            &attr_value); 
    1159             m_loc->attr[m_loc->attr_count++] = attr; 
    1160         } 
    1161  
    1162         /* At this point, 
    1163          * we should have valid rx_policy & tx_policy. 
    1164          */ 
     1253             
    11651254    } 
    11661255    goto PROPAGATE_MEDIA_CREATE; 
     
    11681257BYPASS_SRTP: 
    11691258    srtp->bypass_srtp = PJ_TRUE; 
    1170     member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 
    11711259 
    11721260PROPAGATE_MEDIA_CREATE: 
    1173     return pjmedia_transport_media_create(srtp->real_tp, pool,  
    1174                             member_tp_option, 
    1175                             sdp_local, sdp_remote, media_index); 
     1261    return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool,  
     1262                                        sdp_local, sdp_remote, media_index); 
    11761263} 
    11771264 
     
    11801267static pj_status_t transport_media_start(pjmedia_transport *tp, 
    11811268                                         pj_pool_t *pool, 
    1182                                          pjmedia_sdp_session *sdp_local, 
     1269                                         const pjmedia_sdp_session *sdp_local, 
    11831270                                         const pjmedia_sdp_session *sdp_remote, 
    11841271                                         unsigned media_index) 
     
    11961283    m_rem = sdp_remote->media[media_index]; 
    11971284    m_loc = sdp_local->media[media_index]; 
     1285 
     1286    srtp->remote_prefer_rtp_savp = (pj_stricmp(&m_rem->desc.transport,  
     1287                                   &ID_RTP_SAVP) == 0); 
    11981288 
    11991289    /* For answerer side, this function will just have to start SRTP */ 
     
    12641354            } 
    12651355 
    1266             srtp->tx_policy = srtp->setting.crypto[rem_tag-1]; 
    1267             srtp->rx_policy = tmp_tx_crypto; 
     1356            srtp->tx_policy_neg = srtp->setting.crypto[rem_tag-1]; 
     1357            srtp->rx_policy_neg = tmp_tx_crypto; 
    12681358        } 
    12691359 
     
    12811371        } 
    12821372 
    1283         /* At this point, 
    1284          * we should have valid rx_policy & tx_policy. 
    1285          */ 
     1373        /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 
    12861374    } 
    12871375 
    12881376    /* Got policy_local & policy_remote, let's initalize the SRTP */ 
    1289     status = pjmedia_transport_srtp_start(tp, &srtp->tx_policy, &srtp->rx_policy); 
     1377    status = pjmedia_transport_srtp_start(tp, &srtp->tx_policy_neg, &srtp->rx_policy_neg); 
    12901378    if (status != PJ_SUCCESS) 
    12911379        return status; 
     
    12971385 
    12981386PROPAGATE_MEDIA_START: 
    1299     return pjmedia_transport_media_start(srtp->real_tp, pool,  
     1387    return pjmedia_transport_media_start(srtp->member_tp, pool,  
    13001388                                         sdp_local, sdp_remote, 
    13011389                                         media_index); 
     
    13071395    pj_status_t status; 
    13081396 
    1309     status = pjmedia_transport_media_stop(srtp->real_tp); 
     1397    status = pjmedia_transport_media_stop(srtp->member_tp); 
    13101398    if (status != PJ_SUCCESS) 
    13111399        PJ_LOG(4, (srtp->pool->obj_name,  
Note: See TracChangeset for help on using the changeset viewer.