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); }
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 }
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); }
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); }
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; }