Merge "bridge_softmix: Forward TEXT frames" into 13

This commit is contained in:
George Joseph
2018-04-27 13:17:27 -05:00
committed by Gerrit Code Review
12 changed files with 658 additions and 45 deletions

View File

@@ -63,6 +63,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/features_config.h"
#include "asterisk/pickup.h"
#include "asterisk/test.h"
#include "asterisk/message.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
@@ -91,6 +92,7 @@ static void chan_pjsip_pvt_dtor(void *obj)
/* \brief Asterisk core interaction functions */
static struct ast_channel *chan_pjsip_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg);
static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text);
static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit);
static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -112,6 +114,7 @@ struct ast_channel_tech chan_pjsip_tech = {
.description = "PJSIP Channel Driver",
.requester = chan_pjsip_request,
.send_text = chan_pjsip_sendtext,
.send_text_data = chan_pjsip_sendtext_data,
.send_digit_begin = chan_pjsip_digit_begin,
.send_digit_end = chan_pjsip_digit_end,
.call = chan_pjsip_call,
@@ -128,7 +131,7 @@ struct ast_channel_tech chan_pjsip_tech = {
.queryoption = chan_pjsip_queryoption,
.func_channel_read = pjsip_acf_channel_read,
.get_pvt_uniqueid = chan_pjsip_get_uniqueid,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER | AST_CHAN_TP_SEND_TEXT_DATA
};
/*! \brief SIP session interaction functions */
@@ -2261,50 +2264,99 @@ static struct ast_channel *chan_pjsip_request(const char *type, struct ast_forma
struct sendtext_data {
struct ast_sip_session *session;
char text[0];
struct ast_msg_data *msg;
};
static void sendtext_data_destroy(void *obj)
{
struct sendtext_data *data = obj;
ao2_ref(data->session, -1);
ao2_cleanup(data->session);
ast_free(data->msg);
}
static struct sendtext_data* sendtext_data_create(struct ast_sip_session *session, const char *text)
static struct sendtext_data* sendtext_data_create(struct ast_channel *chan,
struct ast_msg_data *msg)
{
int size = strlen(text) + 1;
struct sendtext_data *data = ao2_alloc(sizeof(*data)+size, sendtext_data_destroy);
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan);
struct sendtext_data *data = ao2_alloc(sizeof(*data), sendtext_data_destroy);
if (!data) {
return NULL;
}
data->session = session;
data->msg = ast_msg_data_dup(msg);
if (!data->msg) {
ao2_cleanup(data);
return NULL;
}
data->session = channel->session;
ao2_ref(data->session, +1);
ast_copy_string(data->text, text, size);
return data;
}
static int sendtext(void *obj)
{
RAII_VAR(struct sendtext_data *, data, obj, ao2_cleanup);
struct sendtext_data *data = obj;
pjsip_tx_data *tdata;
const struct ast_sip_body body = {
const char *body_text = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_BODY);
const char *content_type = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_CONTENT_TYPE);
char *sep;
struct ast_sip_body body = {
.type = "text",
.subtype = "plain",
.body_text = data->text
.body_text = body_text,
};
if (!ast_strlen_zero(content_type)) {
sep = strchr(content_type, '/');
if (sep) {
*sep = '\0';
body.type = content_type;
body.subtype = ++sep;
}
}
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");
pjsip_from_hdr *hdr;
pjsip_name_addr *name_addr;
const char *from = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_FROM);
const char *to = ast_msg_data_get_attribute(data->msg, AST_MSG_DATA_ATTR_TO);
int invalidate_tdata = 0;
ast_sip_create_request("MESSAGE", data->session->inv_session->dlg, data->session->endpoint, NULL, NULL, &tdata);
ast_sip_add_body(tdata, &body);
/*
* If we have a 'from' in the msg, set the display name in the From
* header to it.
*/
if (!ast_strlen_zero(from)) {
hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
name_addr = (pjsip_name_addr *) hdr->uri;
pj_strdup2(tdata->pool, &name_addr->display, from);
invalidate_tdata = 1;
}
/*
* If we have a 'to' in the msg, set the display name in the To
* header to it.
*/
if (!ast_strlen_zero(to)) {
hdr = PJSIP_MSG_TO_HDR(tdata->msg);
name_addr = (pjsip_name_addr *) hdr->uri;
pj_strdup2(tdata->pool, &name_addr->display, to);
invalidate_tdata = 1;
}
if (invalidate_tdata) {
pjsip_tx_data_invalidate_msg(tdata);
}
ast_sip_send_request(tdata, data->session->inv_session->dlg, data->session->endpoint, NULL, NULL);
}
@@ -2312,14 +2364,22 @@ static int sendtext(void *obj)
pjsip_inv_dec_ref(data->session->inv_session);
#endif
ao2_cleanup(data);
return 0;
}
/*! \brief Function called by core to send text on PJSIP session */
static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
static int chan_pjsip_sendtext_data(struct ast_channel *ast, struct ast_msg_data *msg)
{
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(ast, msg);
ast_debug(1, "Sending MESSAGE from '%s' to '%s:%s': %s\n",
ast_msg_data_get_attribute(msg, AST_MSG_DATA_ATTR_FROM),
ast_msg_data_get_attribute(msg, AST_MSG_DATA_ATTR_TO),
ast_channel_name(ast),
ast_msg_data_get_attribute(msg, AST_MSG_DATA_ATTR_BODY));
if (!data) {
return -1;
@@ -2343,6 +2403,28 @@ static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
return 0;
}
static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text)
{
struct ast_msg_data *msg;
int rc;
struct ast_msg_data_attribute attrs[] =
{
{
.type = AST_MSG_DATA_ATTR_BODY,
.value = (char *)text,
}
};
msg = ast_msg_data_alloc(AST_MSG_DATA_SOURCE_TYPE_UNKNOWN, attrs, ARRAY_LEN(attrs));
if (!msg) {
return -1;
}
rc = chan_pjsip_sendtext_data(ast, msg);
ast_free(msg);
return rc;
}
/*! \brief Convert SIP hangup causes to Asterisk hangup causes */
static int hangup_sip2cause(int cause)
{