static gboolean kms_webrtc_session_configure_connection (KmsWebrtcSession * self, KmsSdpSession * sess, SdpMediaConfig * neg_mconf, SdpMediaConfig * remote_mconf, gboolean offerer) { GstSDPMedia *neg_media = kms_sdp_media_config_get_sdp_media (neg_mconf); const gchar *neg_proto_str = gst_sdp_media_get_proto (neg_media); GstSDPMedia *remote_media = kms_sdp_media_config_get_sdp_media (remote_mconf); const gchar *remote_proto_str = gst_sdp_media_get_proto (remote_media); if (g_strcmp0 (neg_proto_str, remote_proto_str) != 0) { GST_WARNING_OBJECT (self, "Negotiated proto ('%s') not matching with remote proto ('%s')", neg_proto_str, remote_proto_str); return FALSE; } if (g_strcmp0 (neg_proto_str, "DTLS/SCTP") != 0) { return FALSE; } kms_webrtc_session_add_connection (self, sess, neg_mconf, offerer); return TRUE; }
static SdpHandler * kms_sdp_agent_get_handler_for_media (KmsSdpAgent * agent, const GstSDPMedia * media) { GSList *l; for (l = agent->priv->handlers; l != NULL; l = l->next) { SdpHandler *sdp_handler; sdp_handler = l->data; if (g_strcmp0 (sdp_handler->media, gst_sdp_media_get_media (media)) != 0) { /* This handler can not manage this media */ continue; } if (!kms_sdp_media_handler_manage_protocol (sdp_handler->handler, gst_sdp_media_get_proto (media))) { continue; } return sdp_handler; } return NULL; }
static GstSDPMedia * reject_media_answer (const GstSDPMedia * offered) { GstSDPMedia *media; const gchar *mid; guint i, len; gst_sdp_media_new (&media); /* [rfc3264] To reject an offered stream, the port number in the */ /* corresponding stream in the answer MUST be set to zero. Any */ /* media formats listed are ignored. */ gst_sdp_media_set_media (media, gst_sdp_media_get_media (offered)); gst_sdp_media_set_port_info (media, 0, 1); gst_sdp_media_set_proto (media, gst_sdp_media_get_proto (offered)); len = gst_sdp_media_formats_len (offered); for (i = 0; i < len; i++) { const gchar *format; format = gst_sdp_media_get_format (offered, i); gst_sdp_media_insert_format (media, i, format); } /* [rfc5888] mid attribute must be present in answer as well */ mid = gst_sdp_media_get_attribute_val (offered, "mid"); if (mid == NULL) { return media; } gst_sdp_media_add_attribute (media, "mid", mid); return media; }
static KmsIRtpConnection * kms_webrtc_session_create_connection (KmsBaseRtpSession * base_rtp_sess, SdpMediaConfig * mconf, const gchar * name, guint16 min_port, guint16 max_port) { KmsWebrtcSession *self = KMS_WEBRTC_SESSION (base_rtp_sess); GstSDPMedia *media = kms_sdp_media_config_get_sdp_media (mconf); KmsWebRtcBaseConnection *conn; self->min_port = min_port; self->max_port = max_port; if (g_strcmp0 (gst_sdp_media_get_proto (media), "DTLS/SCTP") == 0) { GST_DEBUG_OBJECT (self, "Create SCTP connection"); conn = KMS_WEBRTC_BASE_CONNECTION (kms_webrtc_sctp_connection_new (self->agent, self->context, name, min_port, max_port)); } else { GST_DEBUG_OBJECT (self, "Create RTP connection"); conn = KMS_WEBRTC_BASE_CONNECTION (kms_webrtc_connection_new (self->agent, self->context, name)); } return KMS_I_RTP_CONNECTION (conn); }
static gboolean kms_base_rtp_session_configure_connection (KmsBaseRtpSession * self, SdpMediaConfig * neg_mconf, SdpMediaConfig * remote_mconf, gboolean offerer) { GstSDPMedia *neg_media = kms_sdp_media_config_get_sdp_media (neg_mconf); const gchar *neg_proto_str = gst_sdp_media_get_proto (neg_media); const gchar *neg_media_str = gst_sdp_media_get_media (neg_media); GstSDPMedia *remote_media = kms_sdp_media_config_get_sdp_media (remote_mconf); const gchar *remote_proto_str = gst_sdp_media_get_proto (remote_media); const gchar *remote_media_str = gst_sdp_media_get_media (remote_media); gboolean active; if (g_strcmp0 (neg_proto_str, remote_proto_str) != 0) { GST_WARNING_OBJECT (self, "Negotiated proto ('%s') not matching with remote proto ('%s')", neg_proto_str, remote_proto_str); return FALSE; } if (!kms_utils_contains_proto (neg_proto_str, "RTP")) { GST_DEBUG_OBJECT (self, "'%s' protocol does not need RTP connection", neg_proto_str); /* It cannot be managed here but could be managed by the child class */ return FALSE; } if (g_strcmp0 (neg_media_str, remote_media_str) != 0) { GST_WARNING_OBJECT (self, "Negotiated media ('%s') not matching with remote media ('%s')", neg_media_str, remote_media_str); return FALSE; } if (kms_base_rtp_session_process_remote_ssrc (self, remote_media, neg_mconf) == NULL) { return TRUE; /* It cannot be managed here but could be managed by the child class */ } active = sdp_utils_media_is_active (neg_media, offerer); return kms_base_rtp_session_add_connection_for_session (self, neg_mconf, active); }
static gboolean create_media_answer (const GstSDPMedia * media, struct SdpAnswerData *data) { KmsSdpAgent *agent = data->agent; GstSDPMedia *answer_media = NULL; SdpHandler *sdp_handler; GError **err = data->err; SDP_AGENT_LOCK (agent); sdp_handler = kms_sdp_agent_get_handler_for_media (agent, media); SDP_AGENT_UNLOCK (agent); if (sdp_handler == NULL) { GST_WARNING_OBJECT (agent, "No handler for '%s' media proto '%s' found", gst_sdp_media_get_media (media), gst_sdp_media_get_proto (media)); goto answer; } answer_media = kms_sdp_media_handler_create_answer (sdp_handler->handler, data->ctx, media, err); if (answer_media == NULL) { return FALSE; } answer: { SdpMediaConfig *mconf; gboolean do_call = TRUE; if (answer_media == NULL) { answer_media = reject_media_answer (media); do_call = FALSE; } mconf = kms_sdp_message_context_add_media (data->ctx, answer_media, err); if (mconf == NULL) { return FALSE; } if (do_call && data->agent->priv->configure_media_callback_data != NULL) { data->agent->priv->configure_media_callback_data->callback (data->agent, mconf, data->agent->priv->configure_media_callback_data->user_data); } return TRUE; } }
static gboolean kms_sdp_reject_media_handler_init_answer (KmsSdpMediaHandler * handler, const GstSDPMedia * offer, GstSDPMedia * answer, GError ** error) { guint i, len; if (gst_sdp_media_set_media (answer, gst_sdp_media_get_media (offer)) != GST_SDP_OK) { g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER, "Can not set '%s' media ttribute", gst_sdp_media_get_media (offer)); return FALSE; } if (gst_sdp_media_set_proto (answer, gst_sdp_media_get_proto (offer)) != GST_SDP_OK) { g_set_error (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER, "Can not set proto '%s' attribute", gst_sdp_media_get_proto (offer)); return FALSE; } if (gst_sdp_media_set_port_info (answer, 0, 1) != GST_SDP_OK) { g_set_error_literal (error, KMS_SDP_AGENT_ERROR, SDP_AGENT_INVALID_PARAMETER, "Can not set port info attribute"); return FALSE; } len = gst_sdp_media_formats_len (offer); for (i = 0; i < len; i++) { const gchar *format; format = gst_sdp_media_get_format (offer, i); gst_sdp_media_insert_format (answer, i, format); } return TRUE; }
static gboolean kms_sdp_rtp_avpf_media_handler_add_answer_attributes_impl (KmsSdpMediaHandler * handler, const GstSDPMedia * offer, GstSDPMedia * answer, GError ** error) { if (!KMS_SDP_MEDIA_HANDLER_CLASS (parent_class)->add_answer_attributes (handler, offer, answer, error)) { return FALSE; } if (g_strcmp0 (gst_sdp_media_get_proto (offer), SDP_MEDIA_RTP_AVP_PROTO) == 0) { /* Do not add specific feedback parameters in response */ return TRUE; } return kms_sdp_rtp_avpf_media_handler_filter_rtcp_fb_attrs (handler, offer, answer, error); }