summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip/pjsip_transport_events.c55
-rw-r--r--res/res_rtp_asterisk.c70
2 files changed, 99 insertions, 26 deletions
diff --git a/res/res_pjsip/pjsip_transport_events.c b/res/res_pjsip/pjsip_transport_events.c
index c701b8411..cc7b7c077 100644
--- a/res/res_pjsip/pjsip_transport_events.c
+++ b/res/res_pjsip/pjsip_transport_events.c
@@ -114,6 +114,36 @@ static void transport_monitor_dtor(void *vdoomed)
AST_VECTOR_FREE(&monitored->monitors);
}
+/*!
+ * \internal
+ * \brief Do registered callbacks for the transport.
+ * \since 13.21.0
+ *
+ * \param transports Active transports container
+ * \param transport Which transport to do callbacks for.
+ *
+ * \return Nothing
+ */
+static void transport_state_do_reg_callbacks(struct ao2_container *transports, pjsip_transport *transport)
+{
+ struct transport_monitor *monitored;
+
+ monitored = ao2_find(transports, transport->obj_name, OBJ_SEARCH_KEY | OBJ_UNLINK);
+ if (monitored) {
+ int idx;
+
+ for (idx = AST_VECTOR_SIZE(&monitored->monitors); idx--;) {
+ struct transport_monitor_notifier *notifier;
+
+ notifier = AST_VECTOR_GET_ADDR(&monitored->monitors, idx);
+ ast_debug(3, "running callback %p(%p) for transport %s\n",
+ notifier->cb, notifier->data, transport->obj_name);
+ notifier->cb(notifier->data);
+ }
+ ao2_ref(monitored, -1);
+ }
+}
+
/*! \brief Callback invoked when transport state changes occur */
static void transport_state_callback(pjsip_transport *transport,
pjsip_transport_state state, const pjsip_transport_state_info *info)
@@ -147,6 +177,7 @@ static void transport_state_callback(pjsip_transport *transport,
if (!transport->is_shutdown) {
pjsip_transport_shutdown(transport);
}
+ transport_state_do_reg_callbacks(transports, transport);
break;
case PJSIP_TP_STATE_SHUTDOWN:
/*
@@ -157,23 +188,17 @@ static void transport_state_callback(pjsip_transport *transport,
*/
transport->is_shutdown = PJ_TRUE;
- monitored = ao2_find(transports, transport->obj_name,
- OBJ_SEARCH_KEY | OBJ_UNLINK);
- if (monitored) {
- int idx;
-
- for (idx = AST_VECTOR_SIZE(&monitored->monitors); idx--;) {
- struct transport_monitor_notifier *notifier;
-
- notifier = AST_VECTOR_GET_ADDR(&monitored->monitors, idx);
- ast_debug(3, "running callback %p(%p) for transport %s\n",
- notifier->cb, notifier->data, transport->obj_name);
- notifier->cb(notifier->data);
- }
- ao2_ref(monitored, -1);
- }
+ transport_state_do_reg_callbacks(transports, transport);
+ break;
+ case PJSIP_TP_STATE_DESTROY:
+ transport_state_do_reg_callbacks(transports, transport);
break;
default:
+ /*
+ * We have to have a default case because the enum is
+ * defined by a third-party library.
+ */
+ ast_assert(0);
break;
}
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index d0e482405..b010f6c51 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -106,7 +106,7 @@
#define RTCP_PT_APP 204
/* VP8: RTCP Feedback */
/*! Payload Specific Feed Back (From RFC4585 also RFC5104) */
-#define RTCP_PT_PSFB 206
+#define RTCP_PT_PSFB AST_RTP_RTCP_PSFB
#define RTP_MTU 1200
#define DTMF_SAMPLE_RATE_MS 8 /*!< DTMF samples per millisecond */
@@ -5185,6 +5185,7 @@ static const char *rtcp_payload_type2str(unsigned int pt)
#define RTCP_SR_BLOCK_WORD_LENGTH 5
#define RTCP_RR_BLOCK_WORD_LENGTH 6
#define RTCP_HEADER_SSRC_LENGTH 2
+#define RTCP_FB_REMB_BLOCK_WORD_LENGTH 5
static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr)
{
@@ -5266,6 +5267,7 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup);
struct ast_rtp_instance *child;
struct ast_rtp *rtp;
+ struct ast_rtp_rtcp_feedback *feedback;
i = position;
first_word = ntohl(rtcpheader[i]);
@@ -5284,7 +5286,15 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
min_length += (rc * RTCP_RR_BLOCK_WORD_LENGTH);
break;
case RTCP_PT_FUR:
+ break;
case RTCP_PT_PSFB:
+ switch (rc) {
+ case AST_RTP_RTCP_FMT_REMB:
+ min_length += RTCP_FB_REMB_BLOCK_WORD_LENGTH;
+ break;
+ default:
+ break;
+ }
break;
case RTCP_PT_SDES:
case RTCP_PT_BYE:
@@ -5493,6 +5503,7 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
/* Return an AST_FRAME_RTCP frame with the ast_rtp_rtcp_report
* object as a its data */
transport_rtp->f.frametype = AST_FRAME_RTCP;
+ transport_rtp->f.subclass.integer = pt;
transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
memcpy(transport_rtp->f.data.ptr, rtcp_report, sizeof(struct ast_rtp_rtcp_report));
transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_report);
@@ -5514,18 +5525,55 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
f = &transport_rtp->f;
break;
case RTCP_PT_FUR:
- /* Handle RTCP FIR as FUR */
+ /* Handle RTCP FUR as FIR by setting the format to 4 */
+ rc = AST_RTP_RTCP_FMT_FIR;
case RTCP_PT_PSFB:
- if (rtcp_debug_test_addr(addr)) {
- ast_verbose("Received an RTCP Fast Update Request\n");
+ switch (rc) {
+ case AST_RTP_RTCP_FMT_FIR:
+ if (rtcp_debug_test_addr(addr)) {
+ ast_verbose("Received an RTCP Fast Update Request\n");
+ }
+ transport_rtp->f.frametype = AST_FRAME_CONTROL;
+ transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE;
+ transport_rtp->f.datalen = 0;
+ transport_rtp->f.samples = 0;
+ transport_rtp->f.mallocd = 0;
+ transport_rtp->f.src = "RTP";
+ f = &transport_rtp->f;
+ break;
+ case AST_RTP_RTCP_FMT_REMB:
+ /* If REMB support is not enabled ignore this message */
+ if (!ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_REMB)) {
+ break;
+ }
+
+ if (rtcp_debug_test_addr(addr)) {
+ ast_verbose("Received REMB report\n");
+ }
+ transport_rtp->f.frametype = AST_FRAME_RTCP;
+ transport_rtp->f.subclass.integer = pt;
+ transport_rtp->f.stream_num = rtp->stream_num;
+ transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
+ feedback = transport_rtp->f.data.ptr;
+ feedback->fmt = rc;
+
+ /* We don't actually care about the SSRC information in the feedback message */
+ first_word = ntohl(rtcpheader[i + 2]);
+ feedback->remb.br_exp = (first_word >> 18) & ((1 << 6) - 1);
+ feedback->remb.br_mantissa = first_word & ((1 << 18) - 1);
+
+ transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_feedback);
+ transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
+ transport_rtp->f.samples = 0;
+ transport_rtp->f.mallocd = 0;
+ transport_rtp->f.delivery.tv_sec = 0;
+ transport_rtp->f.delivery.tv_usec = 0;
+ transport_rtp->f.src = "RTP";
+ f = &transport_rtp->f;
+ break;
+ default:
+ break;
}
- transport_rtp->f.frametype = AST_FRAME_CONTROL;
- transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE;
- transport_rtp->f.datalen = 0;
- transport_rtp->f.samples = 0;
- transport_rtp->f.mallocd = 0;
- transport_rtp->f.src = "RTP";
- f = &transport_rtp->f;
break;
case RTCP_PT_SDES:
if (rtcp_debug_test_addr(addr)) {