Example #1
0
void janus_dtls_srtp_send_alert(janus_dtls_srtp *dtls) {
	/* Send alert */
	janus_refcount_increase(&dtls->ref);
	if(dtls != NULL && dtls->ssl != NULL) {
		SSL_shutdown(dtls->ssl);
		janus_dtls_fd_bridge(dtls);
	}
	janus_refcount_decrease(&dtls->ref);
}
Example #2
0
int janus_dtls_srtp_create_sctp(janus_dtls_srtp *dtls) {
#ifdef HAVE_SCTP
	if(dtls == NULL)
		return -1;
	janus_ice_component *component = (janus_ice_component *)dtls->component;
	if(component == NULL)
		return -2;
	janus_ice_stream *stream = component->stream;
	if(!stream)
		return -3;
	janus_ice_handle *handle = stream->handle;
	if(!handle || !handle->agent)
		return -4;
	if(janus_flags_is_set(&handle->webrtc_flags, JANUS_ICE_HANDLE_WEBRTC_ALERT))
		return -5;
	dtls->sctp = janus_sctp_association_create(dtls, handle->handle_id, 5000);
	if(dtls->sctp == NULL) {
		JANUS_LOG(LOG_ERR, "[%"SCNu64"] Error creating SCTP association...\n", handle->handle_id);
		return -6;
	}
	/* We need to start it in a thread, since it has blocking accept/connect stuff */
	janus_refcount_increase(&dtls->ref);
	janus_refcount_increase(&dtls->sctp->ref);
	GError *error = NULL;
	char tname[16];
	g_snprintf(tname, sizeof(tname), "sctpinit %"SCNu64, handle->handle_id);
	g_thread_try_new(tname, janus_dtls_sctp_setup_thread, dtls, &error);
	if(error != NULL) {
		/* Something went wrong... */
		janus_refcount_decrease(&dtls->ref);
		janus_refcount_decrease(&dtls->sctp->ref);
		JANUS_LOG(LOG_ERR, "[%"SCNu64"] Got error %d (%s) trying to launch the DTLS-SCTP thread...\n", handle->handle_id, error->code, error->message ? error->message : "??");
		return -7;
	}
	return 0;
#else
	/* Support for datachannels hasn't been built in */
	return -1;
#endif
}
Example #3
0
void janus_sdp_find_preferred_codecs(janus_sdp *sdp, const char **acodec, const char **vcodec) {
	if(sdp == NULL)
		return;
	janus_refcount_increase(&sdp->ref);
	gboolean audio = FALSE, video = FALSE;
	GList *temp = sdp->m_lines;
	while(temp) {
		/* Which media are available? */
		janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
		if(m->type == JANUS_SDP_AUDIO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
			if(audio == FALSE) {
				uint i=0;
				for(i=0; i<janus_audio_codecs; i++) {
					if(janus_sdp_get_codec_pt(sdp, janus_preferred_audio_codecs[i]) > 0) {
						audio = TRUE;
						if(acodec)
							*acodec = janus_preferred_audio_codecs[i];
						break;
					}
				}
			}
		} else if(m->type == JANUS_SDP_VIDEO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
			if(video == FALSE) {
				uint i=0;
				for(i=0; i<janus_video_codecs; i++) {
					if(janus_sdp_get_codec_pt(sdp, janus_preferred_video_codecs[i]) > 0) {
						video = TRUE;
						if(vcodec)
							*vcodec = janus_preferred_video_codecs[i];
						break;
					}
				}
			}
		}
		if(audio && video)
			break;
		temp = temp->next;
	}
	janus_refcount_decrease(&sdp->ref);
}
Example #4
0
void janus_sdp_find_first_codecs(janus_sdp *sdp, const char **acodec, const char **vcodec) {
	if(sdp == NULL)
		return;
	janus_refcount_increase(&sdp->ref);
	gboolean audio = FALSE, video = FALSE;
	GList *temp = sdp->m_lines;
	while(temp) {
		/* Which media are available? */
		janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
		if(m->type == JANUS_SDP_AUDIO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
			if(audio == FALSE && m->ptypes) {
				int pt = GPOINTER_TO_INT(m->ptypes->data);
				const char *codec = janus_sdp_get_codec_name(sdp, pt);
				codec = janus_sdp_match_preferred_codec(m->type, (char *)codec);
				if(codec) {
					audio = TRUE;
					if(acodec)
						*acodec = codec;
				}
			}
		} else if(m->type == JANUS_SDP_VIDEO && m->port > 0 && m->direction != JANUS_SDP_INACTIVE) {
			if(video == FALSE && m->ptypes) {
				int pt = GPOINTER_TO_INT(m->ptypes->data);
				const char *codec = janus_sdp_get_codec_name(sdp, pt);
				codec = janus_sdp_match_preferred_codec(m->type, (char *)codec);
				if(codec) {
					video = TRUE;
					if(vcodec)
						*vcodec = codec;
				}
			}
		}
		if(audio && video)
			break;
		temp = temp->next;
	}
	janus_refcount_decrease(&sdp->ref);
}
Example #5
0
char *janus_sdp_write(janus_sdp *imported) {
	if(!imported)
		return NULL;
	janus_refcount_increase(&imported->ref);
	char *sdp = g_malloc(JANUS_BUFSIZE), buffer[512];
	*sdp = '\0';
	/* v= */
	g_snprintf(buffer, sizeof(buffer), "v=%d\r\n", imported->version);
	g_strlcat(sdp, buffer, JANUS_BUFSIZE);
	/* o= */
	g_snprintf(buffer, sizeof(buffer), "o=%s %"SCNu64" %"SCNu64" IN %s %s\r\n",
		imported->o_name, imported->o_sessid, imported->o_version,
		imported->o_ipv4 ? "IP4" : "IP6", imported->o_addr);
	g_strlcat(sdp, buffer, JANUS_BUFSIZE);
	/* s= */
	g_snprintf(buffer, sizeof(buffer), "s=%s\r\n", imported->s_name);
	g_strlcat(sdp, buffer, JANUS_BUFSIZE);
	/* t= */
	g_snprintf(buffer, sizeof(buffer), "t=%"SCNu64" %"SCNu64"\r\n", imported->t_start, imported->t_stop);
	g_strlcat(sdp, buffer, JANUS_BUFSIZE);
	/* c= */
	if(imported->c_addr != NULL) {
		g_snprintf(buffer, sizeof(buffer), "c=IN %s %s\r\n",
			imported->c_ipv4 ? "IP4" : "IP6", imported->c_addr);
		g_strlcat(sdp, buffer, JANUS_BUFSIZE);
	}
	/* a= */
	GList *temp = imported->attributes;
	while(temp) {
		janus_sdp_attribute *a = (janus_sdp_attribute *)temp->data;
		if(a->value != NULL) {
			g_snprintf(buffer, sizeof(buffer), "a=%s:%s\r\n", a->name, a->value);
		} else {
			g_snprintf(buffer, sizeof(buffer), "a=%s\r\n", a->name);
		}
		g_strlcat(sdp, buffer, JANUS_BUFSIZE);
		temp = temp->next;
	}
	/* m= */
	temp = imported->m_lines;
	while(temp) {
		janus_sdp_mline *m = (janus_sdp_mline *)temp->data;
		g_snprintf(buffer, sizeof(buffer), "m=%s %d %s", m->type_str, m->port, m->proto);
		g_strlcat(sdp, buffer, JANUS_BUFSIZE);
		if(m->port == 0) {
			/* Remove all payload types/formats if we're rejecting the media */
			g_list_free_full(m->fmts, (GDestroyNotify)g_free);
			m->fmts = NULL;
			g_list_free(m->ptypes);
			m->ptypes = NULL;
			m->ptypes = g_list_append(m->ptypes, GINT_TO_POINTER(0));
			g_strlcat(sdp, " 0", JANUS_BUFSIZE);
		} else {
			if(m->proto != NULL && strstr(m->proto, "RTP") != NULL) {
				/* RTP profile, use payload types */
				GList *ptypes = m->ptypes;
				while(ptypes) {
					g_snprintf(buffer, sizeof(buffer), " %d", GPOINTER_TO_INT(ptypes->data));
					g_strlcat(sdp, buffer, JANUS_BUFSIZE);
					ptypes = ptypes->next;
				}
			} else {
				/* Something else, use formats */
				GList *fmts = m->fmts;
				while(fmts) {
					g_snprintf(buffer, sizeof(buffer), " %s", (char *)(fmts->data));
					g_strlcat(sdp, buffer, JANUS_BUFSIZE);
					fmts = fmts->next;
				}
			}
		}
		g_strlcat(sdp, "\r\n", JANUS_BUFSIZE);
		/* c= */
		if(m->c_addr != NULL) {
			g_snprintf(buffer, sizeof(buffer), "c=IN %s %s\r\n",
				m->c_ipv4 ? "IP4" : "IP6", m->c_addr);
			g_strlcat(sdp, buffer, JANUS_BUFSIZE);
		}
		if(m->port > 0) {
			/* b= */
			if(m->b_name != NULL) {
				g_snprintf(buffer, sizeof(buffer), "b=%s:%"SCNu32"\r\n", m->b_name, m->b_value);
				g_strlcat(sdp, buffer, JANUS_BUFSIZE);
			}
		}
		/* a= (note that we don't format the direction if it's JANUS_SDP_DEFAULT) */
		const char *direction = m->direction != JANUS_SDP_DEFAULT ? janus_sdp_mdirection_str(m->direction) : NULL;
		if(direction != NULL) {
			g_snprintf(buffer, sizeof(buffer), "a=%s\r\n", direction);
			g_strlcat(sdp, buffer, JANUS_BUFSIZE);
		}
		GList *temp2 = m->attributes;
		while(temp2) {
			janus_sdp_attribute *a = (janus_sdp_attribute *)temp2->data;
			if(m->port == 0 && strcasecmp(a->name, "mid")) {
				/* This media has been rejected or disabled: we only add the mid attribute, if available */
				temp2 = temp2->next;
				continue;
			}
			if(a->value != NULL) {
				g_snprintf(buffer, sizeof(buffer), "a=%s:%s\r\n", a->name, a->value);
			} else {
				g_snprintf(buffer, sizeof(buffer), "a=%s\r\n", a->name);
			}
			g_strlcat(sdp, buffer, JANUS_BUFSIZE);
			temp2 = temp2->next;
		}
		temp = temp->next;
	}
	janus_refcount_decrease(&imported->ref);
	return sdp;
}