mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-20 12:20:12 +00:00
chan_pjsip: segfault on already disconnected session
On heavy loaded system the TCP/TLS incoming calls could be disconnected by pjproject while these calls are being processed by asterisk. This patch uses functions pjsip_inv_add_ref/pjsip_inv_dec_ref to inform pjproject that an INVITE session is in use. ASTERISK-26482 #close Change-Id: Ia2e3e2f75358cdb530252a9ce158af3d5d9fdf33
This commit is contained in:
@@ -559,6 +559,12 @@ static int answer(void *data)
|
|||||||
struct ast_sip_session *session = data;
|
struct ast_sip_session *session = data;
|
||||||
|
|
||||||
if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||||
|
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
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,6 +581,10 @@ static int answer(void *data)
|
|||||||
ast_sip_session_send_response(session, packet);
|
ast_sip_session_send_response(session, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
pjsip_inv_dec_ref(session->inv_session);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (status == PJ_SUCCESS) ? 0 : -1;
|
return (status == PJ_SUCCESS) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,12 +601,23 @@ static int chan_pjsip_answer(struct ast_channel *ast)
|
|||||||
ast_setstate(ast, AST_STATE_UP);
|
ast_setstate(ast, AST_STATE_UP);
|
||||||
session = ao2_bump(channel->session);
|
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, "Can't increase the session reference counter\n");
|
||||||
|
ao2_ref(session, -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* the answer task needs to be pushed synchronously otherwise a race condition
|
/* the answer task needs to be pushed synchronously otherwise a race condition
|
||||||
can occur between this thread and bridging (specifically when native bridging
|
can occur between this thread and bridging (specifically when native bridging
|
||||||
attempts to do direct media) */
|
attempts to do direct media) */
|
||||||
ast_channel_unlock(ast);
|
ast_channel_unlock(ast);
|
||||||
if (ast_sip_push_task_synchronous(session->serializer, answer, session)) {
|
if (ast_sip_push_task_synchronous(session->serializer, answer, session)) {
|
||||||
ast_log(LOG_WARNING, "Unable to push answer task to the threadpool. Cannot answer call\n");
|
ast_log(LOG_WARNING, "Unable to push answer task to the threadpool. Cannot answer call\n");
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
pjsip_inv_dec_ref(session->inv_session);
|
||||||
|
#endif
|
||||||
ao2_ref(session, -1);
|
ao2_ref(session, -1);
|
||||||
ast_channel_lock(ast);
|
ast_channel_lock(ast);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1105,6 +1126,9 @@ static int indicate(void *data)
|
|||||||
ast_sip_session_send_response(session, packet);
|
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);
|
ao2_ref(ind_data, -1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1132,17 +1156,35 @@ static int transmit_info_with_vidupdate(void *data)
|
|||||||
RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
|
RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
|
||||||
struct pjsip_tx_data *tdata;
|
struct pjsip_tx_data *tdata;
|
||||||
|
|
||||||
|
if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
|
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");
|
ast_log(LOG_ERROR, "Could not create text video update INFO request\n");
|
||||||
return -1;
|
goto failure;
|
||||||
}
|
}
|
||||||
if (ast_sip_add_body(tdata, &body)) {
|
if (ast_sip_add_body(tdata, &body)) {
|
||||||
ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
|
ast_log(LOG_ERROR, "Could not add body to text video update INFO request\n");
|
||||||
return -1;
|
goto failure;
|
||||||
}
|
}
|
||||||
ast_sip_session_send_request(session, tdata);
|
ast_sip_session_send_request(session, tdata);
|
||||||
|
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
pjsip_inv_dec_ref(session->inv_session);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
pjsip_inv_dec_ref(session->inv_session);
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -1185,6 +1227,17 @@ static int update_connected_line_information(void *data)
|
|||||||
{
|
{
|
||||||
struct ast_sip_session *session = data;
|
struct ast_sip_session *session = data;
|
||||||
|
|
||||||
|
if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (ast_channel_state(session->channel) == AST_STATE_UP
|
if (ast_channel_state(session->channel) == AST_STATE_UP
|
||||||
|| session->inv_session->role == PJSIP_ROLE_UAC) {
|
|| session->inv_session->role == PJSIP_ROLE_UAC) {
|
||||||
if (is_colp_update_allowed(session)) {
|
if (is_colp_update_allowed(session)) {
|
||||||
@@ -1222,6 +1275,10 @@ static int update_connected_line_information(void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
pjsip_inv_dec_ref(session->inv_session);
|
||||||
|
#endif
|
||||||
|
|
||||||
ao2_ref(session, -1);
|
ao2_ref(session, -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1335,10 +1392,18 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
|
|||||||
res = ast_rtp_instance_write(media->rtp, &fr);
|
res = ast_rtp_instance_write(media->rtp, &fr);
|
||||||
} else {
|
} else {
|
||||||
ao2_ref(channel->session, +1);
|
ao2_ref(channel->session, +1);
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
if (ast_sip_push_task(channel->session->serializer, transmit_info_with_vidupdate, channel->session)) {
|
if (pjsip_inv_add_ref(channel->session->inv_session) != PJ_SUCCESS) {
|
||||||
|
ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
|
||||||
ao2_cleanup(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");
|
ast_test_suite_event_notify("AST_CONTROL_VIDUPDATE", "Result: Success");
|
||||||
} else {
|
} else {
|
||||||
@@ -1348,7 +1413,17 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
|
|||||||
break;
|
break;
|
||||||
case AST_CONTROL_CONNECTED_LINE:
|
case AST_CONTROL_CONNECTED_LINE:
|
||||||
ao2_ref(channel->session, +1);
|
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");
|
||||||
|
ao2_cleanup(channel->session);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (ast_sip_push_task(channel->session->serializer, update_connected_line_information, channel->session)) {
|
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);
|
ao2_cleanup(channel->session);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1441,9 +1516,23 @@ static int chan_pjsip_indicate(struct ast_channel *ast, int condition, const voi
|
|||||||
|
|
||||||
if (response_code) {
|
if (response_code) {
|
||||||
struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
|
struct indicate_data *ind_data = indicate_data_alloc(channel->session, condition, response_code, data, datalen);
|
||||||
if (!ind_data || ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
|
|
||||||
|
if (!ind_data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
if (pjsip_inv_add_ref(ind_data->session->inv_session) != PJ_SUCCESS) {
|
||||||
|
ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
|
||||||
|
ao2_cleanup(ind_data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ast_sip_push_task(channel->session->serializer, indicate, ind_data)) {
|
||||||
ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could not queue task properly\n",
|
ast_log(LOG_NOTICE, "Cannot send response code %d to endpoint %s. Could not queue task properly\n",
|
||||||
response_code, ast_sorcery_object_get_id(channel->session->endpoint));
|
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);
|
ao2_cleanup(ind_data);
|
||||||
res = -1;
|
res = -1;
|
||||||
}
|
}
|
||||||
@@ -1564,20 +1653,30 @@ static int transfer(void *data)
|
|||||||
struct ast_sip_contact *contact = NULL;
|
struct ast_sip_contact *contact = NULL;
|
||||||
const char *target = trnf_data->target;
|
const char *target = trnf_data->target;
|
||||||
|
|
||||||
/* See if we have an endpoint; if so, use its contact */
|
if (trnf_data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||||
endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", target);
|
ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
|
||||||
if (endpoint) {
|
trnf_data->session->inv_session->cause,
|
||||||
contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
|
pjsip_get_status_text(trnf_data->session->inv_session->cause)->ptr);
|
||||||
if (contact && !ast_strlen_zero(contact->uri)) {
|
} else {
|
||||||
target = contact->uri;
|
/* See if we have an endpoint; if so, use its contact */
|
||||||
|
endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", target);
|
||||||
|
if (endpoint) {
|
||||||
|
contact = ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors);
|
||||||
|
if (contact && !ast_strlen_zero(contact->uri)) {
|
||||||
|
target = contact->uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
|
||||||
|
transfer_redirect(trnf_data->session, target);
|
||||||
|
} else {
|
||||||
|
transfer_refer(trnf_data->session, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ast_channel_state(trnf_data->session->channel) == AST_STATE_RING) {
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
transfer_redirect(trnf_data->session, target);
|
pjsip_inv_dec_ref(trnf_data->session->inv_session);
|
||||||
} else {
|
#endif
|
||||||
transfer_refer(trnf_data->session, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
ao2_ref(trnf_data, -1);
|
ao2_ref(trnf_data, -1);
|
||||||
ao2_cleanup(endpoint);
|
ao2_cleanup(endpoint);
|
||||||
@@ -1595,8 +1694,19 @@ static int chan_pjsip_transfer(struct ast_channel *chan, const char *target)
|
|||||||
return -1;
|
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)) {
|
if (ast_sip_push_task(channel->session->serializer, transfer, trnf_data)) {
|
||||||
ast_log(LOG_WARNING, "Error requesting transfer\n");
|
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);
|
ao2_cleanup(trnf_data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1678,9 +1788,16 @@ static int transmit_info_dtmf(void *data)
|
|||||||
.subtype = "dtmf-relay",
|
.subtype = "dtmf-relay",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(body_text = ast_str_create(32))) {
|
if (!(body_text = ast_str_create(32))) {
|
||||||
ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
|
ast_log(LOG_ERROR, "Could not allocate buffer for INFO DTMF.\n");
|
||||||
return -1;
|
goto failure;
|
||||||
}
|
}
|
||||||
ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
|
ast_str_set(&body_text, 0, "Signal=%c\r\nDuration=%u\r\n", dtmf_data->digit, dtmf_data->duration);
|
||||||
|
|
||||||
@@ -1688,16 +1805,27 @@ static int transmit_info_dtmf(void *data)
|
|||||||
|
|
||||||
if (ast_sip_create_request("INFO", session->inv_session->dlg, session->endpoint, NULL, NULL, &tdata)) {
|
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");
|
ast_log(LOG_ERROR, "Could not create DTMF INFO request\n");
|
||||||
return -1;
|
goto failure;
|
||||||
}
|
}
|
||||||
if (ast_sip_add_body(tdata, &body)) {
|
if (ast_sip_add_body(tdata, &body)) {
|
||||||
ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
|
ast_log(LOG_ERROR, "Could not add body to DTMF INFO request\n");
|
||||||
pjsip_tx_data_dec_ref(tdata);
|
pjsip_tx_data_dec_ref(tdata);
|
||||||
return -1;
|
goto failure;
|
||||||
}
|
}
|
||||||
ast_sip_session_send_request(session, tdata);
|
ast_sip_session_send_request(session, tdata);
|
||||||
|
|
||||||
|
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||||
|
pjsip_inv_dec_ref(session->inv_session);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
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 */
|
/*! \brief Function called by core to stop a DTMF digit */
|
||||||
@@ -1717,8 +1845,19 @@ static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned in
|
|||||||
return -1;
|
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)) {
|
if (ast_sip_push_task(channel->session->serializer, transmit_info_dtmf, dtmf_data)) {
|
||||||
ast_log(LOG_WARNING, "Error sending DTMF via INFO.\n");
|
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);
|
ao2_cleanup(dtmf_data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -2064,11 +2203,21 @@ static int sendtext(void *obj)
|
|||||||
.body_text = data->text
|
.body_text = data->text
|
||||||
};
|
};
|
||||||
|
|
||||||
ast_debug(3, "Sending in dialog SIP message\n");
|
if (data->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
|
||||||
|
ast_log(LOG_ERROR, "Session already DISCONNECTED [reason=%d (%s)]\n",
|
||||||
|
data->session->inv_session->cause,
|
||||||
|
pjsip_get_status_text(data->session->inv_session->cause)->ptr);
|
||||||
|
} else {
|
||||||
|
ast_debug(3, "Sending in dialog SIP message\n");
|
||||||
|
|
||||||
ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
|
ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
|
||||||
ast_sip_add_body(tdata, &body);
|
ast_sip_add_body(tdata, &body);
|
||||||
ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
|
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
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2079,7 +2228,22 @@ static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
|
|||||||
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
|
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
|
||||||
struct sendtext_data *data = sendtext_data_create(channel->session, text);
|
struct sendtext_data *data = sendtext_data_create(channel->session, text);
|
||||||
|
|
||||||
if (!data || ast_sip_push_task(channel->session->serializer, sendtext, data)) {
|
if (!data) {
|
||||||
|
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);
|
ao2_ref(data, -1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user