Bug 803318: Improved handling of constraints and more tests. r=ekr

This commit is contained in:
Adam Roach 2012-11-14 11:25:14 -06:00
parent cc5f3de1d7
commit a19c8d14bd
7 changed files with 1115 additions and 764 deletions

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,7 @@ gsmsdp_set_media_capability(fsmdef_media_t *media,
static fsmdef_media_t *
gsmsdp_add_media_line(fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
uint8_t cap_index, uint16_t level,
cpr_ip_type addr_type);
cpr_ip_type addr_type, boolean offer);
extern cc_media_cap_table_t g_media_table;
@ -124,81 +124,88 @@ static const cc_media_cap_table_t *gsmsdp_get_media_capability (fsmdef_dcb_t *dc
*(dcb_p->media_cap_tbl) = g_media_table;
if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) {
// do not enable video
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
}
if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) {
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
}
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n",
dcb_p->line, dcb_p->call_id, fname);
}
} else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) {
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
}
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n",
dcb_p->line, dcb_p->call_id, fname);
}
} // else if requested is SENDRECV just go by capability
/*
* Turn off two default streams, this is temporary
* until we can handle multiple streams properly
*/
if (sdpmode) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = FALSE;
dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE;
dcb_p->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE;
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE;
dcb_p->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY;
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY;
dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = TRUE;
} else {
dcb_p->media_cap_tbl->cap[CC_DATACHANNEL_1].enabled = FALSE;
if ( dcb_p->video_pref == SDP_DIRECTION_INACTIVE) {
// do not enable video
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].enabled = FALSE;
}
if ( dcb_p->video_pref == SDP_DIRECTION_RECVONLY ) {
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
}
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDONLY ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from sendonly\n",
dcb_p->line, dcb_p->call_id, fname);
}
} else if ( dcb_p->video_pref == SDP_DIRECTION_SENDONLY ) {
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_SENDRECV ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = dcb_p->video_pref;
}
if ( dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction == SDP_DIRECTION_RECVONLY ) {
dcb_p->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_INACTIVE;
DEF_DEBUG(GSM_L_C_F_PREFIX"video capability disabled to SDP_DIRECTION_INACTIVE from recvonly\n",
dcb_p->line, dcb_p->call_id, fname);
}
} // else if requested is SENDRECV just go by capability
}
return (dcb_p->media_cap_tbl);
}
/*
* Process constraints only related to media capabilities. i.e OfferToReceiveAudio, OfferToReceiveVideo
* Process a single constraint for one media capablity
*/
void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints) {
void gsmsdp_process_cap_constraint(cc_media_cap_t *cap,
const char *constraint) {
/* Check constraint string for values "TRUE" or "FALSE"
(currently set in PeerConnectionImpl.cpp, with only
two possible hardcoded values).
TODO -- The values that constraints can take are
fairly narrow and enumerated; they should probably
use an enumeration rather than a string. See bug 811360.
*/
if (constraint[0] == 'F') {
cap->support_direction &= ~SDP_DIRECTION_FLAG_RECV;
} else if (constraint[0] == 'T') {
cap->support_direction |= SDP_DIRECTION_FLAG_RECV;
}
}
/*
* Process constraints only related to media capabilities., i.e
* OfferToReceiveAudio, OfferToReceiveVideo
*/
void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb,
const cc_media_constraints_t* constraints) {
int i = 0;
for (i=0; i<constraints->constraint_count; i++) {
if (strcmp(constraints_table[OfferToReceiveAudio].name, constraints->constraints[i]->name) == 0) {
if (cpr_strcasecmp("FALSE", constraints->constraints[i]->value) == 0) {
dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDONLY;
} else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 &&
TRUE == dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled) {
dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_SENDRECV;
} else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 ) {
dcb->media_cap_tbl->cap[CC_AUDIO_1].enabled = TRUE;
dcb->media_cap_tbl->cap[CC_AUDIO_1].support_direction = SDP_DIRECTION_RECVONLY;
}
}
if (strcmp("OfferToReceiveVideo", constraints->constraints[i]->name) == 0) {
if (cpr_strcasecmp("FALSE", constraints->constraints[i]->value) == 0) {
dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDONLY;
} else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 &&
TRUE == dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled) {
dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_SENDRECV;
} else if (cpr_strcasecmp("TRUE", constraints->constraints[i]->value) == 0 ) {
dcb->media_cap_tbl->cap[CC_VIDEO_1].enabled = TRUE;
dcb->media_cap_tbl->cap[CC_VIDEO_1].support_direction = SDP_DIRECTION_RECVONLY;
}
if (strcmp(constraints_table[OfferToReceiveAudio].name,
constraints->constraints[i]->name) == 0) {
gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_AUDIO_1],
constraints->constraints[i]->value);
} else if (strcmp(constraints_table[OfferToReceiveVideo].name,
constraints->constraints[i]->name) == 0) {
gsmsdp_process_cap_constraint(&dcb->media_cap_tbl->cap[CC_VIDEO_1],
constraints->constraints[i]->value);
}
}
}
/**
@ -1966,8 +1973,10 @@ gsmsdp_add_default_audio_formats_to_local_sdp (fsmdef_dcb_t *dcb_p,
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
}
gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p,
if (media->support_direction != SDP_DIRECTION_INACTIVE) {
gsmsdp_set_media_attributes(local_media_types[type_cnt], local_sdp_p,
level, (uint16_t)local_media_types[type_cnt]);
}
}
/*
@ -1981,10 +1990,12 @@ gsmsdp_add_default_audio_formats_to_local_sdp (fsmdef_dcb_t *dcb_p,
dcb_p->line, dcb_p->call_id, fname);
}
gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level,
local_avt_payload_type);
if (media) {
media->avt_payload_type = local_avt_payload_type;
if (media->support_direction != SDP_DIRECTION_INACTIVE) {
gsmsdp_set_media_attributes(RTP_AVT, local_sdp_p, level,
local_avt_payload_type);
if (media) {
media->avt_payload_type = local_avt_payload_type;
}
}
}
}
@ -2075,8 +2086,10 @@ gsmsdp_add_default_video_formats_to_local_sdp (fsmdef_dcb_t *dcb_p,
line, call_id, fname);
}
gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p,
level, (uint16_t)video_media_types[type_cnt]);
if (media->support_direction != SDP_DIRECTION_INACTIVE) {
gsmsdp_set_video_media_attributes(video_media_types[type_cnt], sdp_p,
level, (uint16_t)video_media_types[type_cnt]);
}
}
}
@ -2268,7 +2281,10 @@ gsmsdp_update_local_sdp_media (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
return;
}
gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr);
if (media->support_direction != SDP_DIRECTION_INACTIVE) {
gsmsdp_set_connection_address(sdp_p, media->level, dcb_p->ice_default_candidate_addr);
}
(void) sdp_set_media_type(sdp_p, level, media->type);
@ -2621,7 +2637,7 @@ gsmsdp_get_remote_avt_payload_type (uint16_t level, void *sdp_p)
*/
static int
gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
fsmdef_media_t *media, boolean offer, boolean initial_offer)
fsmdef_media_t *media, boolean offer, boolean initial_offer, uint16 media_level)
{
static const char fname[] = "gsmsdp_negotiate_codec";
rtp_ptype pref_codec = RTP_NONE;
@ -2659,7 +2675,7 @@ gsmsdp_negotiate_codec (fsmdef_dcb_t *dcb_p, cc_sdp_t *sdp_p,
return (RTP_NONE);
}
level = media->level;
level = media_level;
attr_label = sdp_attr_get_simple_string(sdp_p->dest_sdp,
SDP_ATTR_LABEL, level, 0, 1);
@ -3879,6 +3895,25 @@ gsmsdp_negotiate_remove_media_line (fsmdef_dcb_t *dcb_p,
return (TRUE);
}
/*
* Find a media line based on the media type.
*/
fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb_p, sdp_media_e media_type) {
fsmdef_media_t *media = NULL;
/*
* search the all entries that has a valid media and matches the media type
*/
GSMSDP_FOR_ALL_MEDIA(media, dcb_p) {
if (media->type == media_type) {
/* found a match */
return (media);
}
}
return (NULL);
}
/*
* gsmsdp_negotiate_media_lines
*
@ -3890,8 +3925,7 @@ gsmsdp_negotiate_remove_media_line (fsmdef_dcb_t *dcb_p,
* line exists in the local sdp but is different from the remote sdp,
* change the local sdp to match the remote sdp. If the media line
* is an AUDIO format, negotiate the codec and update the local sdp
* as needed. We will reject all media lines that are not AUDIO and we
* will only accept the first AUDIO media line located.
* as needed.
*
* Parameters:
*
@ -3903,8 +3937,8 @@ gsmsdp_negotiate_remove_media_line (fsmdef_dcb_t *dcb_p,
*
*/
cc_causes_t
gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
boolean initial_offer, boolean offer, boolean notify_stream_added)
gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer,
boolean offer, boolean notify_stream_added, boolean create_answer)
{
static const char fname[] = "gsmsdp_negotiate_media_lines";
cc_causes_t cause = CC_CAUSE_OK;
@ -3957,12 +3991,39 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
* Process each media line in the remote SDP
*/
for (i = 1; i <= num_m_lines; i++) {
unsupported_line = FALSE; /* assume line will be supported */
new_media = FALSE;
media = NULL;
media_type = sdp_get_media_type(sdp_p->dest_sdp, i);
/*
* Only perform these checks when called from createanswer
* because at this point we are concerned as to which m= lines
* have been created in the answer.
*/
if (create_answer) {
/* Since the incoming SDP might not be in the same order as
our media, we find them by type rather than location
for this check. Note that we're not checking for the
value of any _particular_ m= section; we're just checking
whether (at least) one of the specified type exists. */
media = gsmsdp_find_media_by_media_type(dcb_p, media_type);
if (media_type == SDP_MEDIA_AUDIO && !media) {
/* continue if answer will not add this m= line */
continue;
}
if (media_type == SDP_MEDIA_VIDEO && !media) {
continue;
}
if (media_type == SDP_MEDIA_APPLICATION && !media) {
continue;
}
}
port = (uint16_t) sdp_get_media_portnum(sdp_p->dest_sdp, i);
GSM_DEBUG(DEB_L_C_F_PREFIX"Port is %d at %d %d\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname),
@ -3991,7 +4052,9 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
* this has been negiotiated previously (from the
* last offer/answer session).
*/
media = gsmsdp_find_media_by_level(dcb_p, i);
if(!create_answer)
media = gsmsdp_find_media_by_level(dcb_p, i);
if (media == NULL) {
/* No previous media, negotiate adding new media line. */
media = gsmsdp_negotiate_add_media_line(dcb_p, media_type, i,
@ -4029,6 +4092,11 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
break;
}
/* Do not negotiate if media is set to inactive */
if (SDP_DIRECTION_INACTIVE == media->direction) {
break;
}
/* Reset multicast flag and port */
media->is_multicast = FALSE;
media->multicast_port = 0;
@ -4090,7 +4158,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
*/
transport = gsmsdp_negotiate_media_transport(dcb_p, sdp_p,
offer, media,
&crypto_inst);
&crypto_inst, i);
if (transport == SDP_TRANSPORT_INVALID) {
/* unable to negotiate transport */
unsupported_line = TRUE;
@ -4105,7 +4173,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
/*
* Negotiate to a single codec
*/
if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer) ==
if (gsmsdp_negotiate_codec(dcb_p, sdp_p, media, offer, initial_offer, i) ==
RTP_NONE) {
/* unable to negotiate codec */
unsupported_line = TRUE;
@ -4125,7 +4193,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
* parameters to be used for SRTP, if there is any.
*/
gsmsdp_update_negotiated_transport(dcb_p, sdp_p, media,
crypto_inst, transport);
crypto_inst, transport, i);
GSM_DEBUG(DEB_F_PREFIX"local transport after updating negotiated: %d\n",DEB_F_PREFIX_ARGS(GSM, fname), sdp_get_media_transport(dcb_p->sdp->src_sdp, 1));
/*
* Add to or update media line to the local SDP as needed.
@ -4178,7 +4246,7 @@ gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
* Negotiate rtcp-mux
*/
sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, media->level,
sdp_res = sdp_attr_get_rtcp_mux_attribute (sdp_p->dest_sdp, i,
0, SDP_ATTR_RTCP_MUX, 1, &rtcp_mux);
if (SDP_SUCCESS == sdp_res) {
@ -4550,7 +4618,7 @@ gsmsdp_set_media_capability (fsmdef_media_t *media,
static fsmdef_media_t *
gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
uint8_t cap_index, uint16_t level,
cpr_ip_type addr_type)
cpr_ip_type addr_type, boolean offer)
{
static const char fname[] = "gsmsdp_add_media_line";
cc_action_data_t data;
@ -4582,56 +4650,68 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
if (media->support_direction == SDP_DIRECTION_INACTIVE) {
GSM_DEBUG(DEB_L_C_F_PREFIX"feature overrides direction to inactive"
" no media added\n",
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
gsmsdp_remove_media(dcb_p, media);
return (NULL);
DEB_L_C_F_PREFIX_ARGS(GSM, dcb_p->line, dcb_p->call_id, fname));
/*
* For an answer, SDP_DIRECTION_INACTIVE will now add an m=
* line but it is disabled.
*/
if (!offer) {
media->src_port = 0;
} else {
gsmsdp_remove_media(dcb_p, media);
return (NULL);
}
}
/*
* Get the local RTP port. The src port will be set in the dcb
* within the call to cc_call_action(CC_ACTION_OPEN_RCV)
*/
data.open_rcv.is_multicast = FALSE;
data.open_rcv.listen_ip = ip_addr_invalid;
data.open_rcv.port = 0;
data.open_rcv.keep = FALSE;
/*
* Indicate type of media (audio/video etc) becase some for
* supporting video over vieo, the port is obtained from other
* entity.
*/
data.open_rcv.media_type = media->type;
data.open_rcv.media_refid = media->refid;
if (cc_call_action(dcb_p->call_id, dcb_p->line,
CC_ACTION_OPEN_RCV,
&data) != CC_RC_SUCCESS) {
GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n",
dcb_p->line, dcb_p->call_id, fname);
gsmsdp_remove_media(dcb_p, media);
return (NULL);
}
if (media->support_direction != SDP_DIRECTION_INACTIVE) {
/*
* Get the local RTP port. The src port will be set in the dcb
* within the call to cc_call_action(CC_ACTION_OPEN_RCV)
*/
data.open_rcv.is_multicast = FALSE;
data.open_rcv.listen_ip = ip_addr_invalid;
data.open_rcv.port = 0;
data.open_rcv.keep = FALSE;
/*
* Indicate type of media (audio/video etc) becase some for
* supporting video over vieo, the port is obtained from other
* entity.
*/
data.open_rcv.media_type = media->type;
data.open_rcv.media_refid = media->refid;
if (cc_call_action(dcb_p->call_id, dcb_p->line,
CC_ACTION_OPEN_RCV,
&data) != CC_RC_SUCCESS) {
GSM_ERR_MSG(GSM_L_C_F_PREFIX"allocate rx port failed\n",
dcb_p->line, dcb_p->call_id, fname);
gsmsdp_remove_media(dcb_p, media);
return (NULL);
}
/* allocate port successful, save the port */
/* allocate port successful, save the port */
media->src_port = data.open_rcv.port;
media->src_port = data.open_rcv.port;
if(media_cap->type == SDP_MEDIA_APPLICATION) {
if(media_cap->type == SDP_MEDIA_APPLICATION) {
config_get_value(CFGID_SCTP_PORT, &sctp_port, sizeof(sctp_port));
media->sctp_port = sctp_port;
}
}
/*
* Setup the local soruce address.
*/
if (addr_type == CPR_IP_ADDR_IPV6) {
gsmsdp_get_local_source_v6_address(media);
} else if (addr_type == CPR_IP_ADDR_IPV4) {
gsmsdp_get_local_source_v4_address(media);
} else {
GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n",
dcb_p->line, dcb_p->call_id, fname);
gsmsdp_remove_media(dcb_p, media);
return (NULL);
}
/*
* Setup the local soruce address.
*/
if (addr_type == CPR_IP_ADDR_IPV6) {
gsmsdp_get_local_source_v6_address(media);
} else if (addr_type == CPR_IP_ADDR_IPV4) {
gsmsdp_get_local_source_v4_address(media);
} else {
GSM_ERR_MSG(GSM_L_C_F_PREFIX"invalid IP address mode\n",
dcb_p->line, dcb_p->call_id, fname);
gsmsdp_remove_media(dcb_p, media);
return (NULL);
}
/*
@ -4644,33 +4724,35 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
gsmsdp_update_local_sdp_media(dcb_p, dcb_p->sdp, TRUE, media,
media->transport);
if (media->support_direction != SDP_DIRECTION_INACTIVE) {
gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction);
gsmsdp_set_local_sdp_direction(dcb_p, media, media->direction);
/*
* wait until here to set ICE candidates as SDP is now initialized
*/
for (i=0; i<media->candidate_ct; i++) {
gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]);
/*
* wait until here to set ICE candidates as SDP is now initialized
*/
for (i=0; i<media->candidate_ct; i++) {
gsmsdp_set_ice_attribute (SDP_ATTR_ICE_CANDIDATE, level, dcb_p->sdp->src_sdp, media->candidatesp[i]);
}
config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux));
if (rtcpmux) {
gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE);
}
/*
* Since we are initiating an initial offer and opening a
* receive port, store initial media settings.
*/
media->previous_sdp.avt_payload_type = media->avt_payload_type;
media->previous_sdp.direction = media->direction;
media->previous_sdp.packetization_period = media->packetization_period;
media->previous_sdp.payload_type = media->payload;
media->previous_sdp.local_payload_type = media->payload;
break;
}
config_get_value(CFGID_RTCPMUX, &rtcpmux, sizeof(rtcpmux));
if (rtcpmux) {
gsmsdp_set_rtcp_mux_attribute (SDP_ATTR_RTCP_MUX, level, dcb_p->sdp->src_sdp, TRUE);
}
/*
* Since we are initiating an initial offer and opening a
* receive port, store initial media settings.
*/
media->previous_sdp.avt_payload_type = media->avt_payload_type;
media->previous_sdp.direction = media->direction;
media->previous_sdp.packetization_period = media->packetization_period;
media->previous_sdp.payload_type = media->payload;
media->previous_sdp.local_payload_type = media->payload;
break;
default:
/* Unsupported media type, not added */
GSM_DEBUG(DEB_L_C_F_PREFIX"media type %d is not supported\n",
@ -4697,7 +4779,7 @@ gsmsdp_add_media_line (fsmdef_dcb_t *dcb_p, const cc_media_cap_t *media_cap,
*/
cc_causes_t
gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
boolean audio, boolean video, boolean data)
boolean audio, boolean video, boolean data, boolean offer)
{
static const char fname[] = "gsmsdp_create_local_sdp";
uint16_t level;
@ -4729,7 +4811,7 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
media_cap = &media_cap_tbl->cap[0];
level = 0;
for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP; cap_index++) {
for (cap_index = 0; cap_index < CC_MAX_MEDIA_CAP-1; cap_index++) {
/* Build local m lines based on m lines that were in the offered SDP */
media_enabled = TRUE;
@ -4749,7 +4831,7 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
ip_mode = platform_get_ip_address_mode();
if (ip_mode >= CPR_IP_MODE_IPV6) {
if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index,
level, CPR_IP_ADDR_IPV6)
level, CPR_IP_ADDR_IPV6, offer)
== NULL) {
/* fail to add a media line, go back one level */
level = level - 1;
@ -4758,7 +4840,7 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
if (ip_mode == CPR_IP_MODE_DUAL) {
level = level + 1; /* next level */
if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index,
level, CPR_IP_ADDR_IPV4) ==
level, CPR_IP_ADDR_IPV4, offer) ==
NULL) {
/* fail to add a media line, go back one level */
level = level - 1;
@ -4766,7 +4848,7 @@ gsmsdp_create_local_sdp (fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
}
} else {
if (gsmsdp_add_media_line(dcb_p, media_cap, cap_index, level,
CPR_IP_ADDR_IPV4) == NULL) {
CPR_IP_ADDR_IPV4, offer) == NULL) {
/* fail to add a media line, go back one level */
level = level - 1;
}
@ -5044,7 +5126,7 @@ gsmsdp_check_add_local_sdp_media (fsmdef_dcb_t *dcb_p, boolean hold)
/* add a new media */
media = gsmsdp_add_media_line(dcb_p, media_cap, cap_index,
level_to_use, ip_addr_type[i]);
level_to_use, ip_addr_type[i], FALSE);
if (media != NULL) {
/* successfully add a new media line */
if (hold) {
@ -5770,7 +5852,7 @@ gsmsdp_negotiate_answer_sdp (fsm_fcb_t *fcb_p, cc_msgbody_info_t *msg_body)
gsmsdp_set_remote_sdp(dcb_p, dcb_p->sdp);
status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE);
status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, FALSE, FALSE, TRUE, TRUE);
GSM_DEBUG(DEB_F_PREFIX"returns with %d\n",DEB_F_PREFIX_ARGS(GSM, fname), status);
return (status);
}
@ -5808,7 +5890,7 @@ gsmsdp_negotiate_offer_sdp (fsm_fcb_t *fcb_p,
* If a new error code has been added to sdp processing please make sure
* the sip side is aware of it
*/
status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE);
status = gsmsdp_negotiate_media_lines(fcb_p, dcb_p->sdp, init, TRUE, FALSE, FALSE);
return (status);
}
@ -5852,7 +5934,7 @@ gsmsdp_process_offer_sdp (fsm_fcb_t *fcb_p,
* of a session. Otherwise, we will send what we have.
*/
if (init) {
if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE)) {
if ( CC_CAUSE_OK != gsmsdp_create_local_sdp(dcb_p, FALSE, TRUE, TRUE, TRUE, TRUE)) {
return CC_CAUSE_ERROR;
}
} else {

View File

@ -949,18 +949,16 @@ gsmsdp_check_answer_crypto_param (fsmdef_dcb_t *dcb_p, cc_sdp_t * cc_sdp_p,
*/
static sdp_transport_e
gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
fsmdef_media_t *media, uint16_t *crypto_inst)
fsmdef_media_t *media, uint16_t *crypto_inst, uint16 dest_level)
{
sdp_transport_e remote_transport;
sdp_transport_e negotiated_transport = SDP_TRANSPORT_INVALID;
void *sdp_p = cc_sdp_p->dest_sdp;
uint16_t level;
int sdpmode = 0;
config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
level = media->level;
*crypto_inst = 0;
remote_transport = sdp_get_media_transport(sdp_p, level);
remote_transport = sdp_get_media_transport(sdp_p, dest_level);
/* negotiate media transport */
switch (remote_transport) {
@ -975,7 +973,7 @@ gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
if (((sip_regmgr_get_sec_level(dcb_p->line) == ENCRYPTED) &&
FSM_CHK_FLAGS(media->flags, FSM_MEDIA_F_SUPPORT_SECURITY)) || sdpmode) {
/* The signalling with this line is encrypted, try to use SRTP */
if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, level, crypto_inst)) {
if (gsmsdp_select_offer_crypto(dcb_p, sdp_p, dest_level, crypto_inst)) {
/* Found a suitable crypto line from the remote offer */
negotiated_transport = SDP_TRANSPORT_RTPSAVP;
}
@ -1113,14 +1111,14 @@ gsmsdp_negotiate_answer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
sdp_transport_e
gsmsdp_negotiate_media_transport (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
boolean offer, fsmdef_media_t *media,
uint16_t *crypto_inst)
uint16_t *crypto_inst, uint16 level)
{
sdp_transport_e transport;
/* negotiate media transport based on offer or answer from the remote */
if (offer) {
transport = gsmsdp_negotiate_offer_crypto(dcb_p, cc_sdp_p, media,
crypto_inst);
crypto_inst, level);
} else {
transport = gsmsdp_negotiate_answer_crypto(dcb_p, cc_sdp_p, media,
crypto_inst);
@ -1693,7 +1691,8 @@ gsmsdp_update_negotiated_transport (fsmdef_dcb_t *dcb_p,
cc_sdp_t *cc_sdp_p,
fsmdef_media_t *media,
uint16_t crypto_inst,
sdp_transport_e transport)
sdp_transport_e transport,
uint16 dest_level)
{
const char *fname = "gsmsdp_update_negotiated_transport";
sdp_srtp_crypto_suite_t crypto_suite;
@ -1702,7 +1701,7 @@ gsmsdp_update_negotiated_transport (fsmdef_dcb_t *dcb_p,
vcm_crypto_key_t key;
uint16_t level;
level = media->level;
level = dest_level;
/*
* Also detect changes of the crypto parameters for Tx and Rx.
* It is done here to avoid adding last crypto parameters for Tx and

View File

@ -50,7 +50,7 @@ static const gsmsdp_key_table_entry_t constraints_table[] = {
};
cc_causes_t gsmsdp_create_local_sdp(fsmdef_dcb_t *dcb_p, boolean force_streams_enabled,
boolean audio, boolean video, boolean data);
boolean audio, boolean video, boolean data, boolean offer);
void gsmsdp_create_options_sdp(cc_sdp_t **sdp_pp);
void gsmsdp_reset_local_sdp_media(fsmdef_dcb_t *dcb, fsmdef_media_t *media,
boolean hold);
@ -67,8 +67,8 @@ cc_causes_t gsmsdp_process_offer_sdp(fsm_fcb_t *fcb,
cc_msgbody_info_t *msg_body,
boolean init);
cc_causes_t
gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p,
boolean initial_offer, boolean offer, boolean notify_stream_added);
gsmsdp_negotiate_media_lines (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean initial_offer,
boolean offer, boolean notify_stream_added, boolean create_answer);
boolean gsmsdp_sdp_differs_from_previous_sdp(boolean rcv_only,
fsmdef_media_t *media);
@ -90,7 +90,8 @@ extern sdp_transport_e gsmsdp_negotiate_media_transport(fsmdef_dcb_t *dcb_p,
cc_sdp_t *cc_sdp_p,
boolean offer,
fsmdef_media_t *media,
uint16_t *inst_num);
uint16_t *inst_num,
uint16 level);
extern void gsmsdp_update_local_sdp_media_transport(fsmdef_dcb_t *dcb_p,
void *sdp_p,
fsmdef_media_t *media,
@ -100,7 +101,8 @@ extern void gsmsdp_update_negotiated_transport(fsmdef_dcb_t *dcb_p,
cc_sdp_t *cc_sdp_p,
fsmdef_media_t *media,
uint16_t crypto_inst,
sdp_transport_e transport);
sdp_transport_e transport,
uint16 level);
extern void gsmsdp_update_crypto_transmit_key(fsmdef_dcb_t *dcb_p,
fsmdef_media_t *media,
boolean offer,
@ -132,6 +134,6 @@ cc_causes_t gsmsdp_find_level_from_mid(fsmdef_dcb_t * dcb, const char * mid, uin
void gsmsdp_process_cap_constraints(fsmdef_dcb_t *dcb, const cc_media_constraints_t* constraints);
cc_causes_t
gsmsdp_get_offered_media_types (fsm_fcb_t *fcb_p, cc_sdp_t *sdp_p, boolean *has_audio, boolean *has_video, boolean *has_data);
fsmdef_media_t* gsmsdp_find_media_by_media_type(fsmdef_dcb_t *dcb, sdp_media_e media_type);
#endif

View File

@ -18,8 +18,8 @@
cc_media_cap_table_t g_media_table = {
1,
{
{CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_SENDRECV},
{CC_VIDEO_1,SDP_MEDIA_VIDEO,FALSE,TRUE,SDP_DIRECTION_SENDRECV},
{CC_AUDIO_1,SDP_MEDIA_AUDIO,TRUE,TRUE,SDP_DIRECTION_RECVONLY},
{CC_VIDEO_1,SDP_MEDIA_VIDEO,TRUE,TRUE,SDP_DIRECTION_RECVONLY},
{CC_DATACHANNEL_1,SDP_MEDIA_APPLICATION,FALSE,TRUE,SDP_DIRECTION_SENDRECV},
}
};

View File

@ -258,13 +258,18 @@ typedef enum {
SDP_T38_MAX_UDPEC
} sdp_t38_udpec_e;
/* Bitmaps for manipulating sdp_direction_e */
typedef enum {
SDP_DIRECTION_FLAG_SEND=0x01,
SDP_DIRECTION_FLAG_RECV=0x02
} sdp_direction_flag_e;
/* Media flow direction */
typedef enum {
SDP_DIRECTION_INACTIVE,
SDP_DIRECTION_SENDONLY,
SDP_DIRECTION_RECVONLY,
SDP_DIRECTION_SENDRECV,
SDP_DIRECTION_INACTIVE = 0,
SDP_DIRECTION_SENDONLY = SDP_DIRECTION_FLAG_SEND,
SDP_DIRECTION_RECVONLY = SDP_DIRECTION_FLAG_RECV,
SDP_DIRECTION_SENDRECV = SDP_DIRECTION_FLAG_SEND | SDP_DIRECTION_FLAG_RECV,
SDP_MAX_QOS_DIRECTIONS
} sdp_direction_e;

View File

@ -71,6 +71,41 @@ static const std::string strSampleMid = "";
static const unsigned short nSamplelevel = 2;
enum sdpTestFlags
{
SHOULD_SEND_AUDIO = (1<<0),
SHOULD_RECV_AUDIO = (1<<1),
SHOULD_INACTIVE_AUDIO = (1<<2),
SHOULD_REJECT_AUDIO = (1<<3),
SHOULD_SEND_VIDEO = (1<<4),
SHOULD_RECV_VIDEO = (1<<5),
SHOULD_INACTIVE_VIDEO = (1<<6),
SHOULD_REJECT_VIDEO = (1<<7),
SHOULD_SENDRECV_AUDIO = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO,
SHOULD_SENDRECV_VIDEO = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO,
SHOULD_SENDRECV_AV = SHOULD_SENDRECV_AUDIO | SHOULD_SENDRECV_VIDEO,
AUDIO_FLAGS = SHOULD_SEND_AUDIO | SHOULD_RECV_AUDIO
| SHOULD_INACTIVE_AUDIO | SHOULD_REJECT_AUDIO,
VIDEO_FLAGS = SHOULD_SEND_VIDEO | SHOULD_RECV_VIDEO
| SHOULD_INACTIVE_VIDEO | SHOULD_REJECT_VIDEO
};
enum offerAnswerFlags
{
OFFER_NONE = 0, // Sugar to make function calls clearer.
OFFER_AUDIO = (1<<0),
OFFER_VIDEO = (1<<1),
// Leaving some room here for other media types
ANSWER_NONE = 0, // Sugar to make function calls clearer.
ANSWER_AUDIO = (1<<8),
ANSWER_VIDEO = (1<<9),
OFFER_AV = OFFER_AUDIO | OFFER_VIDEO,
ANSWER_AV = ANSWER_AUDIO | ANSWER_VIDEO
};
class TestObserver : public IPeerConnectionObserver
{
public:
@ -480,7 +515,8 @@ class SignalingAgent {
char* offer() const { return offer_; }
char* answer() const { return answer_; }
void CreateOffer(sipcc::MediaConstraints& constraints, bool audio, bool video) {
void CreateOffer(sipcc::MediaConstraints& constraints,
uint32_t offerFlags, uint32_t sdpCheck) {
// Create a media stream as if it came from GUM
Fake_AudioStreamSource *audio_stream =
@ -499,15 +535,13 @@ class SignalingAgent {
uint32_t aHintContents = 0;
if (audio) {
if (offerFlags & OFFER_AUDIO) {
aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
}
if (video) {
if (offerFlags & OFFER_VIDEO) {
aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO;
}
PR_ASSERT(aHintContents);
domMediaStream->SetHintContents(aHintContents);
pc->AddStream(domMediaStream);
@ -517,7 +551,7 @@ class SignalingAgent {
pObserver->state = TestObserver::stateNoResponse;
ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
SDPSanityCheck(pObserver->lastString, audio, video, true);
SDPSanityCheck(pObserver->lastString, sdpCheck, true);
offer_ = pObserver->lastString;
}
@ -526,45 +560,47 @@ class SignalingAgent {
ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateError, kDefaultTimeout);
}
void CreateAnswer(sipcc::MediaConstraints& constraints, bool audio, bool video) {
void CreateAnswer(sipcc::MediaConstraints& constraints, std::string offer,
uint32_t offerAnswerFlags, uint32_t sdpCheck) {
// Create a media stream as if it came from GUM
nsRefPtr<nsDOMMediaStream> domMediaStream = new nsDOMMediaStream();
uint32_t aHintContents = 0;
if (audio) {
if (offerAnswerFlags & ANSWER_AUDIO) {
aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
}
if (video) {
if (offerAnswerFlags & ANSWER_VIDEO) {
aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO;
}
PR_ASSERT(aHintContents);
domMediaStream->SetHintContents(aHintContents);
pc->AddStream(domMediaStream);
// Decide if streams are disabled for offer or answer
// then perform SDP checking based on which stream disabled
pObserver->state = TestObserver::stateNoResponse;
ASSERT_EQ(pc->CreateAnswer(constraints), NS_OK);
ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
SDPSanityCheck(pObserver->lastString, audio, video, false);
SDPSanityCheck(pObserver->lastString, sdpCheck, false);
answer_ = pObserver->lastString;
}
void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, bool audio, bool video) {
// At present, we use the hints field in a stream to find and
// remove it. This only works if the specified hints flags are
// unique among all streams in the PeerConnection. This is not
// generally true, and will need significant revision once
// multiple streams are supported.
void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
uint32_t hints, uint32_t sdpCheck) {
uint32_t aHintContents = 0;
if (!audio) {
aHintContents |= nsDOMMediaStream::HINT_CONTENTS_VIDEO;
}
if (!video) {
aHintContents |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
}
domMediaStream_->SetHintContents(aHintContents);
domMediaStream_->SetHintContents(hints);
// This currently "removes" a stream that has the same audio/video
// hints as were passed in.
// When complete RemoveStream will remove and entire stream and its tracks
// not just disable a track as this is currently doing
pc->RemoveStream(domMediaStream_);
@ -573,7 +609,7 @@ class SignalingAgent {
pObserver->state = TestObserver::stateNoResponse;
ASSERT_EQ(pc->CreateOffer(constraints), NS_OK);
ASSERT_TRUE_WAIT(pObserver->state == TestObserver::stateSuccess, kDefaultTimeout);
SDPSanityCheck(pObserver->lastString, audio, video, true);
SDPSanityCheck(pObserver->lastString, sdpCheck, true);
offer_ = pObserver->lastString;
}
@ -634,27 +670,82 @@ public:
char* answer_;
nsRefPtr<nsDOMMediaStream> domMediaStream_;
private:
void SDPSanityCheck(std::string sdp, bool shouldHaveAudio, bool shouldHaveVideo, bool offer)
void SDPSanityCheck(std::string sdp, uint32_t flags, bool offer)
{
ASSERT_NE(sdp.find("v=0"), std::string::npos);
ASSERT_NE(sdp.find("c=IN IP4"), std::string::npos);
ASSERT_NE(sdp.find("a=fingerprint:sha-256"), std::string::npos);
if (shouldHaveAudio)
{
if (offer)
ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
cout << "SDPSanityCheck flags = " << std::hex << std::showbase
<< flags << std::dec
<< ((flags & SHOULD_SEND_AUDIO)?" SHOULD_SEND_AUDIO":"")
<< ((flags & SHOULD_RECV_AUDIO)?" SHOULD_RECV_AUDIO":"")
<< ((flags & SHOULD_INACTIVE_AUDIO)?" SHOULD_INACTIVE_AUDIO":"")
<< ((flags & SHOULD_REJECT_AUDIO)?" SHOULD_REJECT_AUDIO":"")
<< ((flags & SHOULD_SEND_VIDEO)?" SHOULD_SEND_VIDEO":"")
<< ((flags & SHOULD_RECV_VIDEO)?" SHOULD_RECV_VIDEO":"")
<< ((flags & SHOULD_INACTIVE_VIDEO)?" SHOULD_INACTIVE_VIDEO":"")
<< ((flags & SHOULD_REJECT_VIDEO)?" SHOULD_REJECT_VIDEO":"")
<< endl;
// after negotiation we are left with one codec
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
if ((flags & AUDIO_FLAGS) && offer) {
ASSERT_NE(sdp.find("a=rtpmap:0 PCMU/8000"), std::string::npos);
}
if (shouldHaveVideo)
{
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
switch(flags & AUDIO_FLAGS) {
case 0:
ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
break;
case SHOULD_SEND_AUDIO:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=sendonly"), std::string::npos);
break;
case SHOULD_RECV_AUDIO:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=recvonly"), std::string::npos);
break;
case SHOULD_SENDRECV_AUDIO:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=sendrecv"), std::string::npos);
break;
case SHOULD_INACTIVE_AUDIO:
ASSERT_NE(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find("a=fmtp:101 0-15\r\na=inactive"), std::string::npos);
break;
case SHOULD_REJECT_AUDIO:
ASSERT_EQ(sdp.find("a=rtpmap:109 opus/48000"), std::string::npos);
ASSERT_NE(sdp.find("m=audio 0 "), std::string::npos);
break;
default:
ASSERT_FALSE("Missing case in switch statement");
}
switch(flags & VIDEO_FLAGS) {
case 0:
ASSERT_EQ(sdp.find("a=rtpmap:120 VP8/90000"), std::string::npos);
break;
case SHOULD_SEND_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendonly"),
std::string::npos);
break;
case SHOULD_RECV_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=recvonly"),
std::string::npos);
break;
case SHOULD_SENDRECV_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=sendrecv"),
std::string::npos);
break;
case SHOULD_INACTIVE_VIDEO:
ASSERT_NE(sdp.find("a=rtpmap:120 VP8/90000\r\na=inactive"),
std::string::npos);
break;
case SHOULD_REJECT_VIDEO:
ASSERT_NE(sdp.find("m=video 0 "), std::string::npos);
break;
default:
ASSERT_FALSE("Missing case in switch statement");
}
}
};
@ -668,21 +759,26 @@ class SignalingEnvironment : public ::testing::Environment {
class SignalingTest : public ::testing::Test {
public:
void CreateOffer(sipcc::MediaConstraints& constraints, bool audio, bool video) {
a1_.CreateOffer(constraints, audio, video);
void CreateOffer(sipcc::MediaConstraints& constraints,
uint32_t offerFlags, uint32_t sdpCheck) {
a1_.CreateOffer(constraints, offerFlags, sdpCheck);
}
void CreateSetOffer(sipcc::MediaConstraints& constraints) {
a1_.CreateOffer(constraints, true, true);
void CreateSetOffer(sipcc::MediaConstraints& constraints, uint32_t sdpCheck) {
a1_.CreateOffer(constraints, OFFER_AV, sdpCheck);
a1_.SetLocal(TestObserver::OFFER, a1_.offer());
}
void OfferAnswer(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints,
bool audio, bool video, bool finishAfterAnswer) {
a1_.CreateOffer(aconstraints, audio, video);
void OfferAnswer(sipcc::MediaConstraints& aconstraints,
sipcc::MediaConstraints& bconstraints,
uint32_t offerAnswerFlags,
bool finishAfterAnswer, uint32_t offerSdpCheck,
uint32_t answerSdpCheck) {
a1_.CreateOffer(aconstraints, offerAnswerFlags, offerSdpCheck);
a1_.SetLocal(TestObserver::OFFER, a1_.offer());
a2_.SetRemote(TestObserver::OFFER, a1_.offer());
a2_.CreateAnswer(bconstraints, audio, video);
a2_.CreateAnswer(bconstraints, a1_.offer(),
offerAnswerFlags, answerSdpCheck);
if(true == finishAfterAnswer) {
a2_.SetLocal(TestObserver::ANSWER, a2_.answer());
a1_.SetRemote(TestObserver::ANSWER, a2_.answer());
@ -692,11 +788,14 @@ public:
}
}
void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints) {
a1_.CreateOffer(aconstraints, true, true);
void OfferModifiedAnswer(sipcc::MediaConstraints& aconstraints,
sipcc::MediaConstraints& bconstraints,
uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
a1_.CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
a1_.SetLocal(TestObserver::OFFER, a1_.offer());
a2_.SetRemote(TestObserver::OFFER, a1_.offer());
a2_.CreateAnswer(bconstraints, true, true);
a2_.CreateAnswer(bconstraints, a1_.offer(), OFFER_AV | ANSWER_AV,
answerSdpCheck);
a2_.SetLocal(TestObserver::ANSWER, a2_.answer());
ParsedSDP sdpWrapper(a2_.answer());
sdpWrapper.ReplaceLine("m=audio", "m=audio 65375 RTP/SAVPF 109 8 101\r\n");
@ -707,12 +806,15 @@ public:
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
}
void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints, sipcc::MediaConstraints& bconstraints) {
a1_.CreateOffer(aconstraints, true, true);
void OfferAnswerTrickle(sipcc::MediaConstraints& aconstraints,
sipcc::MediaConstraints& bconstraints,
uint32_t offerSdpCheck, uint32_t answerSdpCheck) {
a1_.CreateOffer(aconstraints, OFFER_AV, offerSdpCheck);
a1_.SetLocal(TestObserver::OFFER, a1_.offer());
ParsedSDP a1_offer(a1_.offer());
a2_.SetRemote(TestObserver::OFFER, a1_offer.sdp_without_ice_);
a2_.CreateAnswer(bconstraints, true, true);
a2_.CreateAnswer(bconstraints, a1_offer.sdp_without_ice_,
OFFER_AV|ANSWER_AV, answerSdpCheck);
a2_.SetLocal(TestObserver::ANSWER, a2_.answer());
ParsedSDP a2_answer(a2_.answer());
a1_.SetRemote(TestObserver::ANSWER, a2_answer.sdp_without_ice_);
@ -723,25 +825,24 @@ public:
ASSERT_TRUE_WAIT(a2_.IceCompleted() == true, kDefaultTimeout);
}
void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints, bool audio, bool video) {
void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints,
uint32_t hints, uint32_t sdpCheck) {
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
a1_.CreateOffer(aconstraints, true, true);
a1_.CreateOfferRemoveStream(constraints, audio, video);
a1_.CreateOffer(aconstraints, OFFER_AV, SHOULD_SENDRECV_AV );
a1_.CreateOfferRemoveStream(constraints, hints, sdpCheck);
}
void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints) {
a1_.CreateOffer(constraints, true, false);
void CreateOfferAudioOnly(sipcc::MediaConstraints& constraints,
uint32_t sdpCheck) {
a1_.CreateOffer(constraints, OFFER_AUDIO, sdpCheck);
}
void CreateOfferRemoveStream(sipcc::MediaConstraints& constraints) {
a1_.CreateOffer(constraints, true, true);
a1_.CreateOfferRemoveStream(constraints, false, true);
}
void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints, const char * candidate, const char * mid, unsigned short level) {
a1_.CreateOffer(constraints, true, true);
void CreateOfferAddCandidate(sipcc::MediaConstraints& constraints,
const char * candidate, const char * mid,
unsigned short level, uint32_t sdpCheck) {
a1_.CreateOffer(constraints, OFFER_AV, sdpCheck);
a1_.AddIceCandidate(candidate, mid, level);
}
@ -758,13 +859,13 @@ TEST_F(SignalingTest, JustInit)
TEST_F(SignalingTest, CreateSetOffer)
{
sipcc::MediaConstraints constraints;
CreateSetOffer(constraints);
CreateSetOffer(constraints, SHOULD_SENDRECV_AV);
}
TEST_F(SignalingTest, CreateOfferAudioVideoConstraintUndefined)
{
sipcc::MediaConstraints constraints;
CreateOffer(constraints, true, true);
CreateOffer(constraints, OFFER_AV, SHOULD_SENDRECV_AV);
}
TEST_F(SignalingTest, CreateOfferNoVideoStream)
@ -772,7 +873,8 @@ TEST_F(SignalingTest, CreateOfferNoVideoStream)
sipcc::MediaConstraints constraints;
constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
CreateOffer(constraints, true, false);
CreateOffer(constraints, OFFER_AUDIO,
SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
}
TEST_F(SignalingTest, CreateOfferNoAudioStream)
@ -780,7 +882,8 @@ TEST_F(SignalingTest, CreateOfferNoAudioStream)
sipcc::MediaConstraints constraints;
constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
CreateOffer(constraints, false, true);
CreateOffer(constraints, OFFER_VIDEO,
SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, CreateOfferDontReceiveAudio)
@ -789,7 +892,8 @@ TEST_F(SignalingTest, CreateOfferDontReceiveAudio)
constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
constraints.setBooleanConstraint("VoiceActivityDetection", true, true);
CreateOffer(constraints, true, true);
CreateOffer(constraints, OFFER_AV,
SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, CreateOfferDontReceiveVideo)
@ -797,7 +901,8 @@ TEST_F(SignalingTest, CreateOfferDontReceiveVideo)
sipcc::MediaConstraints constraints;
constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
CreateOffer(constraints, true, true);
CreateOffer(constraints, OFFER_AV,
SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
}
TEST_F(SignalingTest, CreateOfferRemoveAudioStream)
@ -805,7 +910,8 @@ TEST_F(SignalingTest, CreateOfferRemoveAudioStream)
sipcc::MediaConstraints constraints;
constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
CreateOfferRemoveStream(constraints, false, true);
CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_AUDIO,
SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, CreateOfferDontReceiveAudioRemoveAudioStream)
@ -813,7 +919,8 @@ TEST_F(SignalingTest, CreateOfferDontReceiveAudioRemoveAudioStream)
sipcc::MediaConstraints constraints;
constraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
CreateOfferRemoveStream(constraints, false, true);
CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_AUDIO,
SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, CreateOfferDontReceiveVideoRemoveVideoStream)
@ -821,108 +928,255 @@ TEST_F(SignalingTest, CreateOfferDontReceiveVideoRemoveVideoStream)
sipcc::MediaConstraints constraints;
constraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
constraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
CreateOfferRemoveStream(constraints, true, false);
CreateOfferRemoveStream(constraints, nsDOMMediaStream::HINT_CONTENTS_VIDEO,
SHOULD_SENDRECV_AUDIO);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveAudio)
TEST_F(SignalingTest, OfferAnswerNothingDisabled)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(aconstraints, bconstraints, true, true, false);
sipcc::MediaConstraints constraints;
OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV, false,
SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveVideo)
TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnOffer)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(aconstraints, bconstraints, true, true, false);
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
false, SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO,
SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnOffer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveAudioOnAnswer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
false, SHOULD_SENDRECV_AV,
SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveVideoOnAnswer)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
OfferAnswer(aconstraints, bconstraints, true, true, false);
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AV,
false, SHOULD_SENDRECV_AV,
SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontSendReceiveVideoNoVideoStream)
TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOffer)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
OfferAnswer(aconstraints, bconstraints, true, false, false);
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
false, SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO,
SHOULD_SEND_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontSendReceiveAudioNoAudioStream)
TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOffer)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(aconstraints, bconstraints, false, true, false);
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
false, SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO,
SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveAudioNoAudioStreamDontReceiveVideo)
TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswer)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(aconstraints, bconstraints, false, true, false);
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
false, SHOULD_SENDRECV_AV,
SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
false, SHOULD_SENDRECV_AV,
SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerDontReceiveVideoOnAnswer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AUDIO );
}
TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerDontReceiveAudioOnAnswer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
false, SHOULD_SENDRECV_AV,
SHOULD_REJECT_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnOfferDontReceiveAudioOnOffer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
false, SHOULD_SENDRECV_VIDEO, SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnOfferDontReceiveVideoOnOffer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_AUDIO | ANSWER_AV,
false, SHOULD_SENDRECV_AUDIO, SHOULD_SENDRECV_AUDIO);
}
TEST_F(SignalingTest, OfferAnswerDontReceiveAudioNoAudioStreamOnOfferDontReceiveVideoOnAnswer)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", false, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
answerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
answerconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
OfferAnswer(offerconstraints, answerconstraints, OFFER_VIDEO | ANSWER_AV,
false, SHOULD_SENDRECV_VIDEO, SHOULD_SEND_VIDEO);
}
TEST_F(SignalingTest, CreateOfferAddCandidate)
{
sipcc::MediaConstraints constraints;
CreateOfferAddCandidate(constraints, strSampleCandidate.c_str(), strSampleMid.c_str(), nSamplelevel);
}
TEST_F(SignalingTest, OfferAnswer)
{
sipcc::MediaConstraints constraints;
OfferAnswer(constraints, constraints, true, true, true);
PR_Sleep(kDefaultTimeout * 2); // Wait for completion
CreateOfferAddCandidate(constraints, strSampleCandidate.c_str(),
strSampleMid.c_str(), nSamplelevel,
SHOULD_SENDRECV_AV);
}
// XXX adam@nostrum.com -- This test seems questionable; we need to think
// through what actually needs to be tested here.
TEST_F(SignalingTest, OfferAnswerReNegotiateOfferAnswerDontReceiveVideoNoVideoStream)
{
sipcc::MediaConstraints aconstraints;
aconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
aconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
OfferAnswer(aconstraints, aconstraints, true, true, false);
OfferAnswer(aconstraints, aconstraints, true, true, false);
sipcc::MediaConstraints bconstraints;
bconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
bconstraints.setBooleanConstraint("OfferToReceiveVideo", false, false);
OfferAnswer(aconstraints, aconstraints, OFFER_AV | ANSWER_AV,
false, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
OfferAnswer(bconstraints, bconstraints, OFFER_AUDIO | ANSWER_AV,
false, SHOULD_SENDRECV_AUDIO | SHOULD_SEND_VIDEO,
SHOULD_SENDRECV_AUDIO | SHOULD_INACTIVE_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddAudioStreamOnAnswerNoConstraints)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_VIDEO,
false, SHOULD_SENDRECV_AV,
SHOULD_RECV_AUDIO | SHOULD_SENDRECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddVideoStreamOnAnswerNoConstraints)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_AUDIO,
false, SHOULD_SENDRECV_AV,
SHOULD_SENDRECV_AUDIO | SHOULD_RECV_VIDEO);
}
TEST_F(SignalingTest, OfferAnswerDontAddAudioVideoStreamsOnAnswerNoConstraints)
{
sipcc::MediaConstraints offerconstraints;
offerconstraints.setBooleanConstraint("OfferToReceiveAudio", true, false);
offerconstraints.setBooleanConstraint("OfferToReceiveVideo", true, false);
sipcc::MediaConstraints answerconstraints;
OfferAnswer(offerconstraints, answerconstraints, OFFER_AV | ANSWER_NONE,
false, SHOULD_SENDRECV_AV,
SHOULD_RECV_AUDIO | SHOULD_RECV_VIDEO);
}
TEST_F(SignalingTest, OfferModifiedAnswer)
{
sipcc::MediaConstraints constraints;
OfferModifiedAnswer(constraints, constraints);
OfferModifiedAnswer(constraints, constraints, SHOULD_SENDRECV_AV,
SHOULD_SENDRECV_AV);
PR_Sleep(kDefaultTimeout * 2); // Wait for completion
}
TEST_F(SignalingTest, FullCall)
{
sipcc::MediaConstraints constraints;
OfferAnswer(constraints, constraints, true, true, true);
OfferAnswer(constraints, constraints, OFFER_AV | ANSWER_AV,
true, SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
@ -936,7 +1190,8 @@ TEST_F(SignalingTest, FullCall)
TEST_F(SignalingTest, FullCallTrickle)
{
sipcc::MediaConstraints constraints;
OfferAnswerTrickle(constraints, constraints);
OfferAnswerTrickle(constraints, constraints,
SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written