void audio_sdp_attr_decode(struct audio *a) { const char *attr; if (!a) return; /* This is probably only meaningful for audio data, but may be used with other media types if it makes sense. */ attr = sdp_media_rattr(stream_sdpmedia(a->strm), "ptime"); if (attr) { struct autx *tx = &a->tx; uint32_t ptime_tx = atoi(attr); if (ptime_tx && ptime_tx != a->tx.ptime) { info("audio: peer changed ptime_tx %u -> %u\n", a->tx.ptime, ptime_tx); tx->ptime = ptime_tx; if (tx->ac) { tx->psize = 2 * get_framesize(tx->ac, ptime_tx); } } } }
static void sig_hash_decode(struct zrtp_stream_t *stream, const struct sdp_media *m) { const char *attr_val; struct pl major, minor, hash; uint32_t version; int err; zrtp_status_t s; attr_val = sdp_media_rattr(m, "zrtp-hash"); if (!attr_val) return; err = re_regex(attr_val, strlen(attr_val), "[0-9]+.[0-9]2 [0-9a-f]+", &major, &minor, &hash); if (err || hash.l < ZRTP_SIGN_ZRTP_HASH_LENGTH) { warning("zrtp: malformed zrtp-hash attribute, ignoring...\n"); return; } version = pl_u32(&major) * 100 + pl_u32(&minor); /* more version checks? */ if (version < 110) { warning("zrtp: zrtp-hash: version (%d) is too low, " "ignoring...", version); } s = zrtp_signaling_hash_set(stream, hash.p, (uint32_t)hash.l); if (s != zrtp_status_ok) warning("zrtp: zrtp_signaling_hash_set: status = %d\n", s); }
void audio_sdp_attr_decode(struct audio *a) { const char *attr; if (!a) return; /* This is probably only meaningful for audio data, but may be used with other media types if it makes sense. */ attr = sdp_media_rattr(stream_sdpmedia(a->strm), "ptime"); if (attr) audio_ptime_tx_set(a, atoi(attr)); }
/** * Get a remote attribute from the SDP. Try the media-level first, * and if it does not exist then try session-level. * * @param s SDP Session object * @param m SDP Media object * @param name Remote attribute name * * @return Remote attribute value */ const char *sdp_rattr(const struct sdp_session *s, const struct sdp_media *m, const char *name) { const char *x; x = sdp_media_rattr(m, name); if (x) return x; x = sdp_session_rattr(s, name); if (x) return x; return NULL; }
static void stream_remote_set(struct stream *s) { struct sa rtcp; if (!s) return; /* RFC 5761 */ if (s->cfg.rtcp_mux && sdp_media_rattr(s->sdp, "rtcp-mux")) { if (!s->rtcp_mux) info("%s: RTP/RTCP multiplexing enabled\n", sdp_media_name(s->sdp)); s->rtcp_mux = true; } rtcp_enable_mux(s->rtp, s->rtcp_mux); sdp_media_raddr_rtcp(s->sdp, &rtcp); rtcp_start(s->rtp, s->cname, s->rtcp_mux ? sdp_media_raddr(s->sdp): &rtcp); }
static void stream_remote_set(struct stream *s, const char *cname) { struct sa rtcp; if (!s) return; /* RFC 5761 */ if (config.avt.rtcp_mux && sdp_media_rattr(s->sdp, "rtcp-mux")) { if (!s->rtcp_mux) (void)re_printf("%s: RTP/RTCP multiplexing enabled\n", sdp_media_name(s->sdp)); s->rtcp_mux = true; } rtcp_enable_mux(s->rtp, s->rtcp_mux); sdp_media_raddr_rtcp(s->sdp, &rtcp); rtcp_start(s->rtp, cname, s->rtcp_mux ? sdp_media_raddr(s->sdp): &rtcp); }
static int alloc(struct menc_media **stp, struct menc_sess *sess, struct rtp_sock *rtp, int proto, void *rtpsock, void *rtcpsock, struct sdp_media *sdpm) { struct menc_st *st; const char *rattr = NULL; int layer = 10; /* above zero */ int err = 0; bool mux = (rtpsock == rtcpsock); (void)sess; (void)rtp; if (!stp || !sdpm) return EINVAL; if (proto != IPPROTO_UDP) return EPROTONOSUPPORT; st = (struct menc_st *)*stp; if (!st) { st = mem_zalloc(sizeof(*st), destructor); if (!st) return ENOMEM; st->sdpm = mem_ref(sdpm); err = sdp_media_set_alt_protos(st->sdpm, 4, "RTP/AVP", "RTP/AVPF", "RTP/SAVP", "RTP/SAVPF"); if (err) goto out; if (rtpsock) { st->rtpsock = mem_ref(rtpsock); err |= udp_register_helper(&st->uh_rtp, rtpsock, layer, send_handler, recv_handler, st); } if (rtcpsock && !mux) { st->rtcpsock = mem_ref(rtcpsock); err |= udp_register_helper(&st->uh_rtcp, rtcpsock, layer, send_handler, recv_handler, st); } if (err) goto out; /* set our preferred crypto-suite */ err |= str_dup(&st->crypto_suite, aes_cm_128_hmac_sha1_80); if (err) goto out; err = setup_srtp(st); if (err) goto out; } /* SDP handling */ if (sdp_media_rattr(st->sdpm, "crypto")) { rattr = sdp_media_rattr_apply(st->sdpm, "crypto", sdp_attr_handler, st); if (!rattr) { DEBUG_WARNING("no valid a=crypto attribute from" " remote peer\n"); } } if (!rattr) err = sdp_enc(st, sdpm, 0, st->crypto_suite); out: if (err) mem_deref(st); else *stp = (struct menc_media *)st; return err; }
/** * Get the numerical value from a remote attribute * * @param m SDP Media object * @param name Remote attribute name * * @return Numerical value or 0 if not found */ uint32_t sdp_media_rattr_u32(const struct sdp_media *m, const char *name) { const char *attr = sdp_media_rattr(m, name); return attr ? atoi(attr) : 0; }
static int media_alloc(struct menc_media **stp, struct menc_sess *sess, struct rtp_sock *rtp, struct udp_sock *rtpsock, struct udp_sock *rtcpsock, const struct sa *raddr_rtp, const struct sa *raddr_rtcp, struct sdp_media *sdpm) { struct menc_st *st; const char *rattr = NULL; int layer = 10; /* above zero */ int err = 0; bool mux = (rtpsock == rtcpsock); (void)sess; (void)rtp; (void)raddr_rtp; (void)raddr_rtcp; if (!stp || !sdpm || !sess) return EINVAL; st = (struct menc_st *)*stp; if (!st) { st = mem_zalloc(sizeof(*st), destructor); if (!st) return ENOMEM; st->sess = sess; st->sdpm = mem_ref(sdpm); if (0 == str_cmp(sdp_media_proto(sdpm), "RTP/AVP")) { err = sdp_media_set_alt_protos(st->sdpm, 4, "RTP/AVP", "RTP/AVPF", "RTP/SAVP", "RTP/SAVPF"); if (err) goto out; } if (rtpsock) { st->rtpsock = mem_ref(rtpsock); err |= udp_register_helper(&st->uh_rtp, rtpsock, layer, send_handler, recv_handler, st); } if (rtcpsock && !mux) { st->rtcpsock = mem_ref(rtcpsock); err |= udp_register_helper(&st->uh_rtcp, rtcpsock, layer, send_handler, recv_handler, st); } if (err) goto out; /* set our preferred crypto-suite */ err |= str_dup(&st->crypto_suite, preferred_suite); if (err) goto out; rand_bytes(st->key_tx, sizeof(st->key_tx)); } /* SDP handling */ if (sdp_media_rport(sdpm)) st->got_sdp = true; if (sdp_media_rattr(st->sdpm, "crypto")) { rattr = sdp_media_rattr_apply(st->sdpm, "crypto", sdp_attr_handler, st); if (!rattr) { warning("srtp: no valid a=crypto attribute from" " remote peer\n"); } } if (!rattr) err = sdp_enc(st, sdpm, 1, st->crypto_suite); out: if (err) mem_deref(st); else *stp = (struct menc_media *)st; return err; }