Ticket #467: ticket467.2.patch
File ticket467.2.patch, 16.3 KB (added by nanang, 17 years ago) |
---|
-
pjmedia/include/pjmedia/sdp.h
493 493 unsigned option); 494 494 495 495 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 */ 505 PJ_DECL(pj_status_t) pjmedia_sdp_transport_cmp(const pj_str_t *t1, 506 const pj_str_t *t2); 496 507 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 */ 517 PJ_DECL(pj_status_t) pjmedia_sdp_media_deactivate(pj_pool_t *pool, 518 pjmedia_sdp_media *m); 519 520 497 521 /* ************************************************************************** 498 522 * SDP SESSION DESCRIPTION 499 523 **************************************************************************** -
pjmedia/src/pjmedia/sdp.c
1281 1281 return PJ_SUCCESS; 1282 1282 } 1283 1283 1284 PJ_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 }; 1284 1289 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 1303 PJ_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
212 212 */ 213 213 typedef struct pjmedia_transport pjmedia_transport; 214 214 215 /** 216 * This enumeration specifies the general behaviour of media processing 217 */ 218 typedef 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 215 228 229 } pjmedia_tranport_media_option; 230 216 231 /** 217 232 * This structure describes the operations for the stream transport. 218 233 */ … … 292 307 */ 293 308 pj_status_t (*media_create)(pjmedia_transport *tp, 294 309 pj_pool_t *pool, 310 pjmedia_tranport_media_option option, 295 311 pjmedia_sdp_session *sdp_local, 296 312 const pjmedia_sdp_session *sdp_remote, 297 313 unsigned media_index); … … 516 532 */ 517 533 PJ_INLINE(pj_status_t) pjmedia_transport_media_create(pjmedia_transport *tp, 518 534 pj_pool_t *pool, 535 pjmedia_tranport_media_option option, 519 536 pjmedia_sdp_session *sdp_local, 520 537 const pjmedia_sdp_session *sdp_remote, 521 538 unsigned media_index) 522 539 { 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, 524 541 media_index); 525 542 } 526 543 … … 540 557 * 541 558 * @param tp The media transport. 542 559 * @param pool The memory pool. 560 * @param option The media transport option. 543 561 * @param sdp_local Local SDP. 544 562 * @param sdp_remote Remote SDP. 545 563 * @param media_index Media index to start. -
pjmedia/src/pjmedia/transport_udp.c
35 35 /* Maximum pending write operations */ 36 36 #define MAX_PENDING 4 37 37 38 static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; 39 38 40 /* Pending write buffer */ 39 41 typedef struct pending_write 40 42 { … … 49 51 50 52 pj_pool_t *pool; /**< Memory pool */ 51 53 unsigned options; /**< Transport options. */ 54 unsigned media_options; /**< Transport media options. */ 52 55 void *user_data; /**< Only valid when attached */ 53 56 pj_bool_t attached; /**< Has attachment? */ 54 57 pj_sockaddr rem_rtp_addr; /**< Remote RTP address */ … … 120 123 pj_size_t size); 121 124 static pj_status_t transport_media_create(pjmedia_transport *tp, 122 125 pj_pool_t *pool, 126 pjmedia_tranport_media_option option, 123 127 pjmedia_sdp_session *sdp_local, 124 128 const pjmedia_sdp_session *sdp_remote, 125 129 unsigned media_index); … … 764 768 765 769 static pj_status_t transport_media_create(pjmedia_transport *tp, 766 770 pj_pool_t *pool, 771 pjmedia_tranport_media_option option, 767 772 pjmedia_sdp_session *sdp_local, 768 773 const pjmedia_sdp_session *sdp_remote, 769 774 unsigned media_index) 770 775 { 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; 776 777 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 777 797 return PJ_SUCCESS; 778 798 } 779 799 … … 783 803 const pjmedia_sdp_session *sdp_remote, 784 804 unsigned media_index) 785 805 { 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; 791 807 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 792 826 return PJ_SUCCESS; 793 827 } 794 828 -
pjmedia/src/pjmedia/transport_ice.c
24 24 25 25 #define THIS_FILE "transport_ice.c" 26 26 27 static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; 28 27 29 struct transport_ice 28 30 { 29 31 pjmedia_transport base; 30 32 pj_ice_strans *ice_st; 31 33 pjmedia_ice_cb cb; 34 unsigned media_option; 32 35 33 36 pj_time_val start_ice; 34 37 … … 74 77 pj_size_t size); 75 78 static pj_status_t transport_media_create(pjmedia_transport *tp, 76 79 pj_pool_t *pool, 80 pjmedia_tranport_media_option option, 77 81 pjmedia_sdp_session *sdp_local, 78 82 const pjmedia_sdp_session *sdp_remote, 79 83 unsigned media_index); … … 258 262 */ 259 263 static pj_status_t transport_media_create(pjmedia_transport *tp, 260 264 pj_pool_t *pool, 265 pjmedia_tranport_media_option option, 261 266 pjmedia_sdp_session *sdp_local, 262 267 const pjmedia_sdp_session *sdp_remote, 263 268 unsigned media_index) … … 270 275 unsigned i, cand_cnt; 271 276 pj_status_t status; 272 277 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 273 296 /* Init ICE */ 274 297 ice_role = (sdp_remote==NULL ? PJ_ICE_SESS_ROLE_CONTROLLING : 275 298 PJ_ICE_SESS_ROLE_CONTROLLED); … … 499 522 pj_str_t uname, pass; 500 523 pj_status_t status; 501 524 502 PJ_UNUSED_ARG(sdp_local);503 504 525 PJ_ASSERT_RETURN(tp && pool && sdp_remote, PJ_EINVAL); 505 526 PJ_ASSERT_RETURN(media_index < sdp_remote->media_count, PJ_EINVAL); 506 527 507 528 sdp_med = sdp_remote->media[media_index]; 508 529 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 509 546 /* Get the SDP connection for the media stream. 510 547 * We'll verify later if the SDP connection address is specified 511 548 * as one of the candidate. -
pjmedia/src/pjmedia/transport_srtp.c
35 35 /* Maximum size of packet */ 36 36 #define MAX_BUFFER_LEN 1500 37 37 #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) 43 39 44 40 static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; 45 41 static const pj_str_t ID_RTP_SAVP = { "RTP/SAVP", 8 }; … … 83 79 pj_pool_t *pool; 84 80 pj_lock_t *mutex; 85 81 char tx_buffer[MAX_BUFFER_LEN]; 82 pjmedia_srtp_setting setting; 83 unsigned media_option; 86 84 87 pjmedia_srtp_setting setting;88 85 /* SRTP policy */ 89 86 pj_bool_t session_inited; 90 87 pj_bool_t offerer_side; … … 150 147 pj_size_t size); 151 148 static pj_status_t transport_media_create(pjmedia_transport *tp, 152 149 pj_pool_t *pool, 150 pjmedia_tranport_media_option option, 153 151 pjmedia_sdp_session *sdp_local, 154 152 const pjmedia_sdp_session *sdp_remote, 155 153 unsigned media_index); … … 924 922 925 923 static pj_status_t transport_media_create(pjmedia_transport *tp, 926 924 pj_pool_t *pool, 925 pjmedia_tranport_media_option option, 927 926 pjmedia_sdp_session *sdp_local, 928 927 const pjmedia_sdp_session *sdp_remote, 929 928 unsigned media_index) … … 937 936 pjmedia_sdp_attr *attr; 938 937 pj_str_t attr_value; 939 938 int i, j; 939 unsigned member_tp_option; 940 940 941 941 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; 942 945 943 946 pj_bzero(&srtp->rx_policy, sizeof(srtp->tx_policy)); 944 947 pj_bzero(&srtp->tx_policy, sizeof(srtp->rx_policy)); … … 1130 1133 1131 1134 BYPASS_SRTP: 1132 1135 srtp->bypass_srtp = PJ_TRUE; 1136 member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING; 1133 1137 1134 1138 PROPAGATE_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); 1137 1142 } 1138 1143 1139 1144 … … 1147 1152 struct transport_srtp *srtp = (struct transport_srtp*) tp; 1148 1153 pjmedia_sdp_media *m_rem, *m_loc; 1149 1154 pj_status_t status; 1150 pjmedia_sdp_attr *attr;1151 1155 int i; 1152 1156 1153 1157 PJ_ASSERT_RETURN(tp && pool && sdp_local && sdp_remote, PJ_EINVAL); … … 1171 1175 } 1172 1176 goto BYPASS_SRTP; 1173 1177 } 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 //} 1178 1186 } else if (srtp->setting.use == PJMEDIA_SRTP_MANDATORY) { 1179 1187 if (pj_stricmp(&m_rem->desc.transport, &ID_RTP_SAVP)) { 1180 1188 DEACTIVATE_MEDIA(pool, m_loc); -
pjmedia/src/pjmedia/sdp_neg.c
479 479 } 480 480 481 481 482 /* Chec that transport in the answer match our offer. */482 /* Check that transport in the answer match our offer. */ 483 483 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) 486 490 { 487 /* The transport in the answer is different than the offer! */488 491 return PJMEDIA_SDPNEG_EINVANSTP; 489 492 } 490 493 494 491 495 /* Check if remote has rejected our offer */ 492 496 493 497 if (answer->desc.port == 0) { -
pjmedia/src/pjmedia/session.c
190 190 191 191 /* Transport protocol */ 192 192 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) 198 199 return PJMEDIA_SDPNEG_EINVANSTP; 199 }200 200 201 201 if (pj_stricmp(&local_m->desc.transport, &ID_RTP_AVP) == 0) { 202 202 -
pjsip/src/pjsua-lib/pjsua_media.c
859 859 } 860 860 861 861 /* 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, 863 863 sdp, rem_sdp, MEDIA_IDX); 864 864 if (status != PJ_SUCCESS) { 865 865 if (sip_status_code) *sip_status_code = PJSIP_SC_NOT_ACCEPTABLE; -
pjsip/src/pjsua-lib/pjsua_call.c
2484 2484 if (inv->state != PJSIP_INV_STATE_NULL && 2485 2485 inv->state != PJSIP_INV_STATE_CONFIRMED) 2486 2486 { 2487 //call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);2487 call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); 2488 2488 } 2489 2489 2490 2490 PJSUA_UNLOCK();