ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
session->inv_session->cause,
pjsip_get_status_text(session->inv_session->cause)->ptr);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
SCOPE_EXIT_RTN_VALUE(0, "Disconnected\n");
}
ast_sip_session_send_response(session, packet);
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
-
if (status != PJ_SUCCESS) {
char err[PJ_ERR_MSG_SIZE];
ast_setstate(ast, AST_STATE_UP);
session = ao2_bump(channel->session);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(session->inv_session) != PJ_SUCCESS) {
- ast_log(LOG_ERROR, "Couldn't increase the session reference counter\n");
- ao2_ref(session, -1);
- SCOPE_EXIT_RTN_VALUE(-1, "Couldn't increase the session reference counter\n");
- }
-#endif
-
/* the answer task needs to be pushed synchronously otherwise a race condition
can occur between this thread and bridging (specifically when native bridging
attempts to do direct media) */
if (res == -1) {
ast_log(LOG_ERROR,"Cannot answer '%s': Unable to push answer task to the threadpool.\n",
ast_channel_name(session->channel));
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
}
ao2_ref(session, -1);
ast_channel_lock(ast);
ast_sip_session_send_response(session, packet);
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
ao2_ref(ind_data, -1);
return 0;
ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
session->inv_session->cause,
pjsip_get_status_text(session->inv_session->cause)->ptr);
- goto failure;
+ return -1;
}
if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
- goto failure;
+ return -1;
}
if (ast_sip_add_body(tdata, &body)) {
ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
- goto failure;
+ return -1;
}
ast_sip_session_send_request(session, tdata);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
-
return 0;
-
-failure:
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
- return -1;
-
}
/*!
ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
session->inv_session->cause,
pjsip_get_status_text(session->inv_session->cause)->ptr);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
ao2_ref(session, -1);
return -1;
}
}
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
-
ao2_ref(session, -1);
return 0;
}
res = ast_rtp_instance_write(media->rtp, &fr);
} else {
ao2_ref(channel->session, +1);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
- ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
+ if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
ao2_cleanup(channel->session);
- } else {
-#endif
- if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
- ao2_cleanup(channel->session);
- }
-#ifdef HAVE_PJSIP_INV_SESSION_REF
}
-#endif
}
ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
} else {
break;
case AST_CONTROL_CONNECTED_LINE:
ao2_ref(channel->session, +1);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
- ao2_cleanup(channel->session);
- SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't increase the session reference counter\n",
- ast_channel_name(ast));
- }
-#endif
if (ast_sip_push_task(channel->session->serializer, update_connected_line_information, channel->session)) {
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(channel->session->inv_session);
-#endif
ao2_cleanup(channel->session);
}
break;
if (!ind_data) {
SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc indicate data\n", ast_channel_name(ast));
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(ind_data->session->inv_session) != PJ_SUCCESS) {
- ao2_cleanup(ind_data);
- SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't increase the session reference counter\n", ast_channel_name(ast));
- }
-#endif
+
if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
ast_log(LOG_ERROR, "%s: Cannot send response code %d to endpoint %s. Could not queue task properly\n",
ast_channel_name(ast), response_code, ast_sorcery_object_get_id(channel->session->endpoint));
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(ind_data->session->inv_session);
-#endif
ao2_cleanup(ind_data);
res = -1;
}
}
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(trnf_data->session->inv_session);
-#endif
-
ao2_ref(trnf_data, -1);
ao2_cleanup(endpoint);
ao2_cleanup(contact);
return -1;
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(trnf_data->session->inv_session) != PJ_SUCCESS) {
- ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
- ao2_cleanup(trnf_data);
- return -1;
- }
-#endif
-
if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
ast_log(LOG_WARNING, "Error requesting transfer\n");
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(trnf_data->session->inv_session);
-#endif
ao2_cleanup(trnf_data);
return -1;
}
ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
session->inv_session->cause,
pjsip_get_status_text(session->inv_session->cause)->ptr);
- goto failure;
+ return -1;
}
if (!(body_text = ast_str_create(32))) {
ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
- goto failure;
+ return -1;
}
ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
- goto failure;
+ return -1;
}
if (ast_sip_add_body(tdata, &body)) {
ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
pjsip_tx_data_dec_ref(tdata);
- goto failure;
+ return -1;
}
ast_sip_session_send_request(session, tdata);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
-
return 0;
-
-failure:
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(session->inv_session);
-#endif
- return -1;
-
}
/*! \brief Function called by core to stop a DTMF digit */
return -1;
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(dtmf_data->session->inv_session) != PJ_SUCCESS) {
- ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
- ao2_cleanup(dtmf_data);
- return -1;
- }
-#endif
-
if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(dtmf_data->session->inv_session);
-#endif
ao2_cleanup(dtmf_data);
return -1;
}
ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(data->session->inv_session);
-#endif
-
ao2_cleanup(data);
return 0;
return -1;
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(data->session->inv_session) != PJ_SUCCESS) {
- ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
- ao2_ref(data, -1);
- return -1;
- }
-#endif
-
if (ast_sip_push_task(channel->session->serializer, sendtext, data)) {
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(data->session->inv_session);
-#endif
ao2_ref(data, -1);
return -1;
}
ast_dsp_free(session->dsp);
if (session->inv_session) {
- pjsip_dlg_dec_session(session->inv_session->dlg, &session_module);
+ struct pjsip_dialog *dlg = session->inv_session->dlg;
+
+ /* The INVITE session uses the dialog pool for memory, so we need to
+ * decrement its reference first before that of the dialog.
+ */
+
+#ifdef HAVE_PJSIP_INV_SESSION_REF
+ pjsip_inv_dec_ref(session->inv_session);
+#endif
+ pjsip_dlg_dec_session(dlg, &session_module);
}
ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name);
}
ast_sip_dialog_set_serializer(inv_session->dlg, session->serializer);
ast_sip_dialog_set_endpoint(inv_session->dlg, endpoint);
+
+ /* When a PJSIP INVITE session is created it is created with a reference
+ * count of 1, with that reference being managed by the underlying state
+ * of the INVITE session itself. When the INVITE session transitions to
+ * a DISCONNECTED state that reference is released. This means we can not
+ * rely on that reference to ensure the INVITE session remains for the
+ * lifetime of our session. To ensure it does we add our own reference
+ * and release it when our own session goes away, ensuring that the INVITE
+ * session remains for the lifetime of session.
+ */
+
+#ifdef HAVE_PJSIP_INV_SESSION_REF
+ if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
+ ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
+ return NULL;
+ }
+#endif
+
pjsip_dlg_inc_session(inv_session->dlg, &session_module);
inv_session->mod_data[session_module.id] = ao2_bump(session);
session->contact = ao2_bump(contact);
ast_sip_session_get_name(invite->session),
invite->session->inv_session->cause,
pjsip_get_status_text(invite->session->inv_session->cause)->ptr);
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(invite->session->inv_session);
-#endif
SCOPE_EXIT_RTN_VALUE(-1);
}
handle_incoming_request(invite->session, invite->rdata);
end:
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(invite->session->inv_session);
-#endif
SCOPE_EXIT_RTN_VALUE(0, "%s\n", ast_sip_session_get_name(invite->session));
}
* process handling has successfully completed.
*/
-
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
- ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
- /* Dialog's lock and a reference are removed in new_invite_initial_answer */
- if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
- /* Terminate the session if it wasn't done in the answer */
- pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
- }
- SCOPE_EXIT_RTN("Couldn't add invite session reference\n");
- }
-#endif
-
session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
if (!session) {
/* Dialog's lock and reference are removed in new_invite_initial_answer */
/* Terminate the session if it wasn't done in the answer */
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
}
-#ifdef HAVE_PJSIP_INV_SESSION_REF
- pjsip_inv_dec_ref(inv_session);
-#endif
SCOPE_EXIT_RTN("Couldn't create session\n");
}
session->call_direction = AST_SIP_SESSION_INCOMING_CALL;