summaryrefslogtreecommitdiff
path: root/res/res_pjsip_messaging.c
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2013-12-11 20:24:50 +0000
committerKevin Harwell <kharwell@digium.com>2013-12-11 20:24:50 +0000
commitc602b086edb3bda8e3406c39b55285f0762b1f67 (patch)
tree68256d7f795b30e2bc88d6662d912353dc0fdcbc /res/res_pjsip_messaging.c
parent90108b15a0bfb0a7fe88a12b4afbcf1086f18df9 (diff)
res_pjsip_messaging: send message to a default outbound endpoint
In some cases messages need to be sent to a direct URI (sip:<ip address>). This patch adds in that support by using a default outbound endpoint. When sending messages, if no endpoint can be found then the default one is used. To facilitate this a new default_outbound_endpoint option was added to the globals section for pjsip.conf. Review: https://reviewboard.asterisk.org/r/2944/ ........ Merged revisions 403680 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403687 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_pjsip_messaging.c')
-rw-r--r--res/res_pjsip_messaging.c108
1 files changed, 70 insertions, 38 deletions
diff --git a/res/res_pjsip_messaging.c b/res/res_pjsip_messaging.c
index b66ee0b11..00923b23b 100644
--- a/res/res_pjsip_messaging.c
+++ b/res/res_pjsip_messaging.c
@@ -80,13 +80,17 @@ static enum pjsip_status_code get_destination(const pjsip_rx_data *rdata, const
*/
static enum pjsip_status_code check_content_type(const pjsip_rx_data *rdata)
{
- if (ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type,
- "text",
- "plain")) {
- return PJSIP_SC_OK;
+ int res;
+ if (rdata->msg_info.msg->body && rdata->msg_info.msg->body->len) {
+ res = ast_sip_is_content_type(
+ &rdata->msg_info.msg->body->content_type, "text", "plain");
} else {
- return PJSIP_SC_UNSUPPORTED_MEDIA_TYPE;
+ res = rdata->msg_info.ctype &&
+ !pj_strcmp2(&rdata->msg_info.ctype->media.type, "text") &&
+ !pj_strcmp2(&rdata->msg_info.ctype->media.subtype, "plain");
}
+
+ return res ? PJSIP_SC_OK : PJSIP_SC_UNSUPPORTED_MEDIA_TYPE;
}
/*!
@@ -96,9 +100,9 @@ static enum pjsip_status_code check_content_type(const pjsip_rx_data *rdata)
*
* \param fromto 'From' or 'To' field containing 'sip:'
*/
-static const char* skip_sip(const char *fromto)
+static char* skip_sip(char *fromto)
{
- const char *p;
+ char *p;
/* need to be one past 'sip:' or 'sips:' */
if (!(p = strstr(fromto, "sip"))) {
@@ -119,6 +123,7 @@ static const char* skip_sip(const char *fromto)
* Expects the given 'fromto' to be in one of the following formats:
* sip[s]:endpoint[/aor]
* sip[s]:endpoint[/uri]
+ * sip[s]:uri <-- will use default outbound endpoint
*
* If an optional aor is given it will try to find an associated uri
* to return. If an optional uri is given then that will be returned,
@@ -127,30 +132,37 @@ static const char* skip_sip(const char *fromto)
* \param fromto 'From' or 'To' field with possible endpoint
* \param uri Optional uri to return
*/
-static struct ast_sip_endpoint* get_endpoint(const char *fromto, char **uri)
+static struct ast_sip_endpoint* get_endpoint(char *fromto, char **uri)
{
- const char *name = skip_sip(fromto);
+ char *name, *aor_uri;
struct ast_sip_endpoint* endpoint;
- struct ast_sip_aor *aor;
+ RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
- if ((*uri = strchr(name, '/'))) {
- *(*uri)++ = '\0';
- } else if ((*uri = strchr(name, '@'))) {
- *(*uri) = '\0';
- }
-
- /* endpoint is required */
- if (ast_strlen_zero(name)) {
- return NULL;
+ name = skip_sip(fromto);
+ if ((aor_uri = strchr(name, '/'))) {
+ *aor_uri++ = '\0';
+ } else if ((aor_uri = strchr(name, '@'))) {
+ /* format was endpoint@ */
+ *aor_uri = '\0';
}
- if (!(endpoint = ast_sorcery_retrieve_by_id(
+ if (ast_strlen_zero(name) || !(endpoint = ast_sorcery_retrieve_by_id(
ast_sip_get_sorcery(), "endpoint", name))) {
- return NULL;
+ /* assume sending to direct uri -
+ use default outbound endpoint */
+ *uri = ast_strdup(fromto);
+ return ast_sip_default_outbound_endpoint();
}
- if (*uri && (aor = ast_sip_location_retrieve_aor(*uri))) {
- *uri = (char*)ast_sip_location_retrieve_first_aor_contact(aor)->uri;
+ *uri = aor_uri;
+ if (*uri) {
+ if ((aor = ast_sip_location_retrieve_aor(*uri)) &&
+ (contact = ast_sip_location_retrieve_first_aor_contact(aor))) {
+ *uri = (char*)contact->uri;
+ }
+ /* need to copy because contact-uri might go away*/
+ *uri = ast_strdup(*uri);
}
return endpoint;
@@ -163,13 +175,12 @@ static struct ast_sip_endpoint* get_endpoint(const char *fromto, char **uri)
* \param tdata The outgoing message data structure
* \param from Info to potentially copy into the 'From' header
*/
-static void update_from(pjsip_tx_data *tdata, const char *from)
+static void update_from(pjsip_tx_data *tdata, char *from)
{
pjsip_name_addr *from_name_addr;
pjsip_sip_uri *from_uri;
pjsip_uri *parsed;
- char *uri;
-
+ RAII_VAR(char *, uri, NULL, ast_free);
RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
if (ast_strlen_zero(from)) {
@@ -182,7 +193,20 @@ static void update_from(pjsip_tx_data *tdata, const char *from)
if (ast_strlen_zero(uri)) {
/* if no aor/uri was specified get one from the endpoint */
- uri = (char*)ast_sip_location_retrieve_contact_from_aor_list(endpoint->aors)->uri;
+ RAII_VAR(struct ast_sip_contact *, contact,
+ ast_sip_location_retrieve_contact_from_aor_list(
+ endpoint->aors), ao2_cleanup);
+
+ if (!contact || ast_strlen_zero(contact->uri)) {
+ ast_log(LOG_WARNING, "No contact found for endpoint %s\n",
+ ast_sorcery_object_get_id(endpoint));
+ return;
+ }
+
+ if (uri) {
+ ast_free(uri);
+ }
+ uri = ast_strdup(contact->uri);
}
/* get current 'from' hdr & uri - going to overwrite some fields */
@@ -341,6 +365,7 @@ static enum pjsip_status_code vars_to_headers(const struct ast_msg *msg, pjsip_t
static int headers_to_vars(const pjsip_rx_data *rdata, struct ast_msg *msg)
{
char *c;
+ char name[MAX_HDR_SIZE];
char buf[MAX_HDR_SIZE];
int res = 0;
pjsip_hdr *h = rdata->msg_info.msg->hdr.next;
@@ -350,10 +375,11 @@ static int headers_to_vars(const pjsip_rx_data *rdata, struct ast_msg *msg)
if ((res = pjsip_hdr_print_on(h, buf, sizeof(buf)-1)) > 0) {
buf[res] = '\0';
if ((c = strchr(buf, ':'))) {
- ast_copy_string(buf, ast_skip_blanks(c + 1), sizeof(buf)-(c-buf));
+ ast_copy_string(buf, ast_skip_blanks(c + 1), sizeof(buf));
}
- if ((res = ast_msg_set_var(msg, pj_strbuf(&h->name), buf)) != 0) {
+ ast_copy_pj_str(name, &h->name, sizeof(name));
+ if ((res = ast_msg_set_var(msg, name, buf)) != 0) {
break;
}
}
@@ -375,10 +401,14 @@ static int headers_to_vars(const pjsip_rx_data *rdata, struct ast_msg *msg)
*/
static int print_body(pjsip_rx_data *rdata, char *buf, int len)
{
- int res = rdata->msg_info.msg->body->print_body(
- rdata->msg_info.msg->body, buf, len);
+ int res;
+
+ if (!rdata->msg_info.msg->body || !rdata->msg_info.msg->body->len) {
+ return 0;
+ }
- if (res < 0) {
+ if ((res = rdata->msg_info.msg->body->print_body(
+ rdata->msg_info.msg->body, buf, len)) < 0) {
return res;
}
@@ -500,30 +530,32 @@ static int msg_send(void *data)
};
pjsip_tx_data *tdata;
- char *uri;
-
+ RAII_VAR(char *, uri, NULL, ast_free);
RAII_VAR(struct ast_sip_endpoint *, endpoint, get_endpoint(
mdata->to, &uri), ao2_cleanup);
+
if (!endpoint) {
- ast_log(LOG_ERROR, "SIP MESSAGE - Endpoint not found in %s\n", mdata->to);
+ ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not find endpoint and "
+ "no default outbound endpoint configured\n");
return -1;
}
if (ast_sip_create_request("MESSAGE", NULL, endpoint, uri, &tdata)) {
- ast_log(LOG_ERROR, "SIP MESSAGE - Could not create request\n");
+ ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not create request\n");
return -1;
}
if (ast_sip_add_body(tdata, &body)) {
pjsip_tx_data_dec_ref(tdata);
- ast_log(LOG_ERROR, "SIP MESSAGE - Could not add body to request\n");
+ ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not add body to request\n");
return -1;
}
update_from(tdata, mdata->from);
vars_to_headers(mdata->msg, tdata);
+
if (ast_sip_send_request(tdata, NULL, endpoint)) {
- ast_log(LOG_ERROR, "SIP MESSAGE - Could not send request\n");
+ ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not send request\n");
return -1;
}