📄 sdp_neg_test.c
字号:
"c=IN IP4 host.atlanta.example.com\r\n"
"t=0 0\r\n"
"m=audio 0 RTP/AVP 0\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"m=audio 51372 RTP/AVP 97 101\r\n"
"a=rtpmap:97 iLBC/8000\r\n"
"a=rtpmap:101 telephone-event/8000\r\n"
}
}
},
/* test 11: */
{
/*********************************************************************
* RFC 4317 Sample 2.6: Audio with Telephone-Events (Bob's view)
*
* Difference:
* - Bob's SDP version number
* - Bob's initial capability are expanded with multiple m lines
* and more formats
*/
"RFC 4317 section 2.6: Audio with Telephone-Events (Bob's view)",
1,
{
{
REMOTE_OFFER,
/* Received Alice's offer: */
"v=0\r\n"
"o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
"s=alice\r\n"
"c=IN IP4 host.atlanta.example.com\r\n"
"t=0 0\r\n"
"m=audio 49170 RTP/AVP 0\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"m=audio 51372 RTP/AVP 97 101\r\n"
"a=rtpmap:97 iLBC/8000\r\n"
"a=rtpmap:101 telephone-event/8000\r\n",
/* Bob's initial capability also has video: */
"v=0\r\n"
"o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
"s=bob\r\n"
"c=IN IP4 host.biloxi.example.com\r\n"
"t=0 0\r\n"
"m=audio 49170 RTP/AVP 4 97 101\r\n"
"a=rtpmap:4 G723/8000\r\n"
"a=rtpmap:97 iLBC/8000\r\n"
"a=rtpmap:101 telephone-event/8000\r\n"
"m=video 1000 RTP/AVP 31\r\n"
"a=rtpmap:31 H261/90000\r\n",
/* Bob's answer should be: */
"v=0\r\n"
"o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
"s=bob\r\n"
"c=IN IP4 host.biloxi.example.com\r\n"
"t=0 0\r\n"
"m=audio 0 RTP/AVP 0\r\n"
"a=rtpmap:0 PCMU/8000\r\n"
"m=audio 49170 RTP/AVP 97 101\r\n"
"a=rtpmap:97 iLBC/8000\r\n"
"a=rtpmap:101 telephone-event/8000\r\n",
}
}
},
};
static const char *find_diff(const char *s1, const char *s2,
int *line)
{
*line = 1;
while (*s2 && *s1) {
if (*s2 != *s1)
return s2;
if (*s2 == '\n')
++*line;
++s2, ++s1;
}
return s2;
}
static int compare_sdp_string(const char *cmp_title,
const char *title1,
const pjmedia_sdp_session *sdp1,
const char *title2,
const pjmedia_sdp_session *sdp2,
pj_status_t logical_cmp)
{
char sdpbuf1[1024], sdpbuf2[1024];
pj_ssize_t len1, len2;
len1 = pjmedia_sdp_print(sdp1, sdpbuf1, sizeof(sdpbuf1));
if (len1 < 1) {
PJ_LOG(3,(THIS_FILE," error: printing sdp1"));
return -1;
}
sdpbuf1[len1] = '\0';
len2 = pjmedia_sdp_print(sdp2, sdpbuf2, sizeof(sdpbuf2));
if (len2 < 1) {
PJ_LOG(3,(THIS_FILE," error: printing sdp2"));
return -1;
}
sdpbuf2[len2] = '\0';
if (logical_cmp != PJ_SUCCESS) {
char errbuf[80];
pjmedia_strerror(logical_cmp, errbuf, sizeof(errbuf));
PJ_LOG(3,(THIS_FILE,"%s mismatch: %s\n"
"%s:\n"
"%s\n"
"%s:\n"
"%s\n",
cmp_title,
errbuf,
title1, sdpbuf1,
title2, sdpbuf2));
return -1;
} else if (strcmp(sdpbuf1, sdpbuf2) != 0) {
int line;
const char *diff;
PJ_LOG(3,(THIS_FILE,"%s mismatch:\n"
"%s:\n"
"%s\n"
"%s:\n"
"%s\n",
cmp_title,
title1, sdpbuf1,
title2, sdpbuf2));
diff = find_diff(sdpbuf1, sdpbuf2, &line);
PJ_LOG(3,(THIS_FILE,"Difference: line %d:\n"
"%s",
line, diff));
return -1;
} else {
return 0;
}
}
static int offer_answer_test(pj_pool_t *pool, pjmedia_sdp_neg **p_neg,
struct offer_answer *oa)
{
pjmedia_sdp_session *sdp1;
pjmedia_sdp_neg *neg;
pj_status_t status;
status = pjmedia_sdp_parse(pool, oa->sdp1, pj_native_strlen(oa->sdp1),
&sdp1);
if (status != PJ_SUCCESS) {
app_perror(status, " error: unexpected parse status for sdp1");
return -10;
}
status = pjmedia_sdp_validate(sdp1);
if (status != PJ_SUCCESS) {
app_perror(status, " error: sdp1 validation failed");
return -15;
}
neg = *p_neg;
if (oa->type == LOCAL_OFFER) {
/*
* Local creates offer first.
*/
pjmedia_sdp_session *sdp2, *sdp3;
const pjmedia_sdp_session *active;
if (neg == NULL) {
/* Create negotiator with local offer. */
status = pjmedia_sdp_neg_create_w_local_offer(pool, sdp1, &neg);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_create_w_local_offer");
return -20;
}
*p_neg = neg;
} else {
/* Modify local offer */
status = pjmedia_sdp_neg_modify_local_offer(pool, neg, sdp1);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_modify_local_offer");
return -30;
}
}
/* Parse and validate remote answer */
status = pjmedia_sdp_parse(pool, oa->sdp2, pj_native_strlen(oa->sdp2),
&sdp2);
if (status != PJ_SUCCESS) {
app_perror(status, " error: parsing sdp2");
return -40;
}
status = pjmedia_sdp_validate(sdp2);
if (status != PJ_SUCCESS) {
app_perror(status, " error: sdp2 validation failed");
return -50;
}
/* Give the answer to negotiator. */
status = pjmedia_sdp_neg_set_remote_answer(pool, neg, sdp2);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_rx_remote_answer");
return -60;
}
/* Negotiate remote answer with local answer */
status = pjmedia_sdp_neg_negotiate(pool, neg, 0);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_negotiate");
return -70;
}
/* Get the local active media. */
status = pjmedia_sdp_neg_get_active_local(neg, &active);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_get_local");
return -80;
}
/* Parse and validate the correct active media. */
status = pjmedia_sdp_parse(pool, oa->sdp3, pj_native_strlen(oa->sdp3),
&sdp3);
if (status != PJ_SUCCESS) {
app_perror(status, " error: parsing sdp3");
return -90;
}
status = pjmedia_sdp_validate(sdp3);
if (status != PJ_SUCCESS) {
app_perror(status, " error: sdp3 validation failed");
return -100;
}
/* Compare active with sdp3 */
status = pjmedia_sdp_session_cmp(active, sdp3, 0);
if (status != PJ_SUCCESS) {
app_perror(status, " error: active local comparison mismatch");
compare_sdp_string("Logical cmp after negotiatin remote answer",
"Active local sdp from negotiator", active,
"The correct active local sdp", sdp3,
status);
return -110;
}
/* Compare the string representation oa both sdps */
status = compare_sdp_string("String cmp after negotiatin remote answer",
"Active local sdp from negotiator", active,
"The correct active local sdp", sdp3,
PJ_SUCCESS);
if (status != 0)
return -120;
} else {
/*
* Remote creates offer first.
*/
pjmedia_sdp_session *sdp2, *sdp3;
const pjmedia_sdp_session *answer;
if (neg == NULL) {
/* Parse and validate initial local capability */
status = pjmedia_sdp_parse(pool, oa->sdp2, pj_native_strlen(oa->sdp2),
&sdp2);
if (status != PJ_SUCCESS) {
app_perror(status, " error: parsing sdp2");
return -200;
}
status = pjmedia_sdp_validate(sdp2);
if (status != PJ_SUCCESS) {
app_perror(status, " error: sdp2 validation failed");
return -210;
}
/* Create negotiator with remote offer. */
status = pjmedia_sdp_neg_create_w_remote_offer(pool, sdp2, sdp1, &neg);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_create_w_remote_offer");
return -220;
}
*p_neg = neg;
} else {
/* Received subsequent offer from remote. */
status = pjmedia_sdp_neg_set_remote_offer(pool, neg, sdp1);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_rx_remote_offer");
return -230;
}
}
/* Negotiate. */
status = pjmedia_sdp_neg_negotiate(pool, neg, 0);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_negotiate");
return -240;
}
/* Get our answer. */
status = pjmedia_sdp_neg_get_active_local(neg, &answer);
if (status != PJ_SUCCESS) {
app_perror(status, " error: pjmedia_sdp_neg_get_local");
return -250;
}
/* Parse the correct answer. */
status = pjmedia_sdp_parse(pool, oa->sdp3, pj_native_strlen(oa->sdp3),
&sdp3);
if (status != PJ_SUCCESS) {
app_perror(status, " error: parsing sdp3");
return -260;
}
/* Validate the correct answer. */
status = pjmedia_sdp_validate(sdp3);
if (status != PJ_SUCCESS) {
app_perror(status, " error: sdp3 validation failed");
return -270;
}
/* Compare answer from negotiator and the correct answer */
status = pjmedia_sdp_session_cmp(sdp3, answer, 0);
if (status != PJ_SUCCESS) {
compare_sdp_string("Logical cmp after negotiating remote offer",
"Local answer from negotiator", answer,
"The correct local answer", sdp3,
status);
return -280;
}
/* Compare the string representation oa both answers */
status = compare_sdp_string("String cmp after negotiating remote offer",
"Local answer from negotiator", answer,
"The correct local answer", sdp3,
PJ_SUCCESS);
if (status != 0)
return -290;
}
return 0;
}
static int perform_test(pj_pool_t *pool, int test_index)
{
pjmedia_sdp_neg *neg = NULL;
unsigned i;
int rc;
for (i=0; i<test[test_index].offer_answer_count; ++i) {
rc = offer_answer_test(pool, &neg, &test[test_index].offer_answer[i]);
if (rc != 0) {
PJ_LOG(3,(THIS_FILE, " test %d offer answer %d failed with status %d",
test_index, i, rc));
return rc;
}
}
return 0;
}
int sdp_neg_test()
{
unsigned i;
int status;
for (i=START_TEST; i<PJ_ARRAY_SIZE(test); ++i) {
pj_pool_t *pool;
pool = pj_pool_create(mem, "sdp_neg_test", 4000, 4000, NULL);
if (!pool)
return PJ_ENOMEM;
PJ_LOG(3,(THIS_FILE," test %d: %s", i, test[i].title));
status = perform_test(pool, i);
pj_pool_release(pool);
if (status != 0) {
return status;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -