summaryrefslogtreecommitdiff
path: root/channels/chan_pjsip.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_pjsip.c')
-rw-r--r--channels/chan_pjsip.c112
1 files changed, 97 insertions, 15 deletions
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index dde7416c3..b4eb711f7 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -61,6 +61,7 @@
#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"
@@ -86,6 +87,7 @@ static struct ast_channel *chan_pjsip_request(const char *type, struct ast_forma
static struct ast_channel *chan_pjsip_request_with_stream_topology(const char *type,
struct ast_stream_topology *topology, 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);
@@ -109,6 +111,7 @@ struct ast_channel_tech chan_pjsip_tech = {
.requester = chan_pjsip_request,
.requester_with_stream_topology = chan_pjsip_request_with_stream_topology,
.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,
@@ -125,7 +128,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 */
@@ -2539,50 +2542,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);
}
@@ -2590,14 +2642,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;
@@ -2621,6 +2681,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)
{