diff --git a/src/libosmocc/helper.c b/src/libosmocc/helper.c index 6f2a718..c2e7bf3 100644 --- a/src/libosmocc/helper.c +++ b/src/libosmocc/helper.c @@ -54,6 +54,11 @@ osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, vo } const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec) +{ + return osmo_cc_helper_audio_accept_te(conf, priv, codecs, receiver, msg, session_p, codec_p, NULL, force_our_codec); +} + +const char *osmo_cc_helper_audio_accept_te(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, osmo_cc_session_codec_t **telephone_event_p, int force_our_codec) { char offer_sdp[65536]; const char *accept_sdp; @@ -136,6 +141,8 @@ const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *pr osmo_cc_rtp_open(selected_media); osmo_cc_rtp_connect(selected_media); *codec_p = selected_codec; + if (telephone_event_p) + *telephone_event_p = telephone_event; accept_sdp = osmo_cc_session_send_answer(*session_p); if (!accept_sdp) { @@ -148,9 +155,15 @@ const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *pr } int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p) +{ + return osmo_cc_helper_audio_negotiate_te(msg, session_p, codec_p, NULL); +} + +int osmo_cc_helper_audio_negotiate_te(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, osmo_cc_session_codec_t **telephone_event_p) { char sdp[65536]; osmo_cc_session_media_t *media; + osmo_cc_session_codec_t *codec; int rc; if (!(*session_p)) { @@ -178,10 +191,17 @@ int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **sessi /* skip not accepted codecs */ if (!codec->accepted) continue; - /* select first codec, if one was accpeted */ - if (!(*codec_p)) { - LOGP(DCC, LOGL_DEBUG, "Select codec '%s'.\n", codec->payload_name); - *codec_p = codec; + if (!!strcasecmp(codec->payload_name, "telephone-event")) { + /* select first codec, if one was accpeted */ + if (!(*codec_p)) { + LOGP(DCC, LOGL_DEBUG, "Select codec '%s'.\n", codec->payload_name); + *codec_p = codec; + } + } else { + if (telephone_event_p && !(*telephone_event_p)) { + LOGP(DCC, LOGL_DEBUG, "select telephone event codec.\n"); + *telephone_event_p = codec; + } } } if (*codec_p) { diff --git a/src/libosmocc/helper.h b/src/libosmocc/helper.h index 9b18ac0..a48bd8e 100644 --- a/src/libosmocc/helper.h +++ b/src/libosmocc/helper.h @@ -9,5 +9,7 @@ struct osmo_cc_helper_audio_codecs { osmo_cc_session_t *osmo_cc_helper_audio_offer(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, int debug); const char *osmo_cc_helper_audio_accept(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, int force_our_codec); +const char *osmo_cc_helper_audio_accept_te(osmo_cc_session_config_t *conf, void *priv, struct osmo_cc_helper_audio_codecs *codecs, void (*receiver)(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len), osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, osmo_cc_session_codec_t **telephone_event_p, int force_our_codec); int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p); +int osmo_cc_helper_audio_negotiate_te(osmo_cc_msg_t *msg, osmo_cc_session_t **session_p, osmo_cc_session_codec_t **codec_p, osmo_cc_session_codec_t **telephone_event_p); diff --git a/src/libosmocc/rtp.c b/src/libosmocc/rtp.c index 31104b7..84f15a7 100644 --- a/src/libosmocc/rtp.c +++ b/src/libosmocc/rtp.c @@ -366,6 +366,30 @@ void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, ui free(payload); } +/* dito, but with absolute sequence and timestamp */ +void osmo_cc_rtp_send_ts(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, uint16_t tx_sequence, uint32_t tx_timestamp, void *priv) +{ + uint8_t *payload = NULL; + int payload_len = 0; + + if (!codec || !codec->media->rtp_ofd.fd) + return; + + if (codec->encoder) + codec->encoder(data, len, &payload, &payload_len, priv); + else { + payload = data; + payload_len = len; + } + + rtp_send(&codec->media->rtp_sa, codec->media->rtp_slen, codec->media->rtp_ofd.fd, payload, payload_len, marker, codec->payload_type_remote, tx_sequence, tx_timestamp, codec->media->tx_ssrc); + codec->media->tx_sequence = tx_sequence; + codec->media->tx_timestamp = tx_timestamp; + + if (codec->encoder) + free(payload); +} + static void check_port_translation(struct sockaddr_storage *sa, struct sockaddr_storage *media_sa, const char *what) { struct sockaddr_in6 *sa6, *sa6_2; diff --git a/src/libosmocc/rtp.h b/src/libosmocc/rtp.h index ea1b31f..854c253 100644 --- a/src/libosmocc/rtp.h +++ b/src/libosmocc/rtp.h @@ -3,5 +3,6 @@ void osmo_cc_set_rtp_ports(osmo_cc_session_config_t *conf, uint16_t from, uint16 int osmo_cc_rtp_open(osmo_cc_session_media_t *media); int osmo_cc_rtp_connect(osmo_cc_session_media_t *media); void osmo_cc_rtp_send(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, int inc_sequence, int inc_timestamp, void *priv); +void osmo_cc_rtp_send_ts(osmo_cc_session_codec_t *codec, uint8_t *data, int len, uint8_t marker, uint16_t tx_sequence, uint32_t tx_timestamp, void *priv); void osmo_cc_rtp_close(osmo_cc_session_media_t *media);