diff options
Diffstat (limited to 'res')
-rw-r--r-- | res/res_pjsip.c | 30 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_transport_events.c | 55 | ||||
-rw-r--r-- | res/res_pjsip_outbound_publish.c | 3 | ||||
-rw-r--r-- | res/res_pjsip_outbound_registration.c | 7 | ||||
-rw-r--r-- | res/res_pjsip_session.c | 8 | ||||
-rw-r--r-- | res/res_pjsip_t38.c | 6 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 71 |
7 files changed, 132 insertions, 48 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 935a5598e..7c9929740 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1366,12 +1366,17 @@ If <literal>0</literal> no timeout. Time in fractional seconds. </para></description> </configOption> - <configOption name="authenticate_qualify" default="no"> - <synopsis>Authenticates a qualify request if needed</synopsis> - <description><para> - If true and a qualify request receives a challenge or authenticate response + <configOption name="authenticate_qualify"> + <synopsis>Authenticates a qualify challenge response if needed</synopsis> + <description> + <para>If true and a qualify request receives a challenge response then authentication is attempted before declaring the contact available. - </para></description> + </para> + <note><para>This option does nothing as we will always complete + the challenge response authentication if the qualify request is + challenged. + </para></note> + </description> </configOption> <configOption name="outbound_proxy"> <synopsis>Outbound proxy used when sending OPTIONS request</synopsis> @@ -1565,12 +1570,17 @@ If <literal>0</literal> no timeout. Time in fractional seconds. </para></description> </configOption> - <configOption name="authenticate_qualify" default="no"> - <synopsis>Authenticates a qualify request if needed</synopsis> - <description><para> - If true and a qualify request receives a challenge or authenticate response + <configOption name="authenticate_qualify"> + <synopsis>Authenticates a qualify challenge response if needed</synopsis> + <description> + <para>If true and a qualify request receives a challenge response then authentication is attempted before declaring the contact available. - </para></description> + </para> + <note><para>This option does nothing as we will always complete + the challenge response authentication if the qualify request is + challenged. + </para></note> + </description> </configOption> <configOption name="outbound_proxy"> <synopsis>Outbound proxy used when sending OPTIONS request</synopsis> 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_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c index 75e74a26f..8befbc1e8 100644 --- a/res/res_pjsip_outbound_publish.c +++ b/res/res_pjsip_outbound_publish.c @@ -362,7 +362,8 @@ static struct ast_sip_event_publisher_handler *find_publisher_handler_for_event_ /*! \brief Helper function which cancels the refresh timer on a publisher */ static void cancel_publish_refresh(struct sip_outbound_publisher *publisher) { - if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &publisher->timer)) { + if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), + &publisher->timer, 0)) { /* The timer was successfully cancelled, drop the refcount of the publisher */ ao2_ref(publisher, -1); } diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index d0f754604..2839ecbab 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -512,7 +512,8 @@ static struct ast_sip_endpoint_identifier line_identifier = { /*! \brief Helper function which cancels the timer on a client */ static void cancel_registration(struct sip_outbound_registration_client_state *client_state) { - if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &client_state->timer)) { + if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), + &client_state->timer, client_state->timer.id)) { /* The timer was successfully cancelled, drop the refcount of client_state */ ao2_ref(client_state, -1); } @@ -1129,8 +1130,8 @@ static struct sip_outbound_registration_state *sip_outbound_registration_state_a } state->client_state->status = SIP_REGISTRATION_UNREGISTERED; - state->client_state->timer.user_data = state->client_state; - state->client_state->timer.cb = sip_outbound_registration_timer_cb; + pj_timer_entry_init(&state->client_state->timer, 0, state->client_state, + sip_outbound_registration_timer_cb); state->client_state->transport_name = ast_strdup(registration->transport); state->client_state->registration_name = ast_strdup(ast_sorcery_object_get_id(registration)); diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index f25201731..d13b372be 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -2702,10 +2702,8 @@ int ast_sip_session_defer_termination(struct ast_sip_session *session) session->defer_end = 1; session->ended_while_deferred = 0; - session->scheduled_termination.id = 0; ao2_ref(session, +1); - session->scheduled_termination.user_data = session; - session->scheduled_termination.cb = session_termination_cb; + pj_timer_entry_init(&session->scheduled_termination, 0, session, session_termination_cb); res = (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(), &session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0; @@ -2727,8 +2725,8 @@ int ast_sip_session_defer_termination(struct ast_sip_session *session) */ static void sip_session_defer_termination_stop_timer(struct ast_sip_session *session) { - if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), - &session->scheduled_termination)) { + if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), + &session->scheduled_termination, session->scheduled_termination.id)) { ao2_ref(session, -1); } } diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c index 333295fe6..eba0b36e8 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -142,7 +142,8 @@ static void t38_change_state(struct ast_sip_session *session, struct ast_sip_ses new_state, old_state, session->channel ? ast_channel_name(session->channel) : "<gone>"); - if (pj_timer_heap_cancel(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), &state->timer)) { + if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()), + &state->timer, 0)) { ast_debug(2, "Automatic T.38 rejection on channel '%s' terminated\n", session->channel ? ast_channel_name(session->channel) : "<gone>"); ao2_ref(session, -1); @@ -248,8 +249,7 @@ static struct t38_state *t38_state_get_or_alloc(struct ast_sip_session *session) state = datastore->data; /* This will get bumped up before scheduling */ - state->timer.user_data = session; - state->timer.cb = t38_automatic_reject_timer_cb; + pj_timer_entry_init(&state->timer, 0, session, t38_automatic_reject_timer_cb); datastore->data = state; diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index d0e482405..c87e6fb77 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,56 @@ 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_PLI: + 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)) { |