summaryrefslogtreecommitdiff
path: root/res/res_pjsip_messaging.c
diff options
context:
space:
mode:
Diffstat (limited to 'res/res_pjsip_messaging.c')
-rw-r--r--res/res_pjsip_messaging.c129
1 files changed, 57 insertions, 72 deletions
diff --git a/res/res_pjsip_messaging.c b/res/res_pjsip_messaging.c
index f80261417..db9752553 100644
--- a/res/res_pjsip_messaging.c
+++ b/res/res_pjsip_messaging.c
@@ -47,40 +47,10 @@ const pjsip_method pjsip_message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7} };
#define MAX_HDR_SIZE 512
#define MAX_BODY_SIZE 1024
-#define MAX_EXTEN_SIZE 256
#define MAX_USER_SIZE 128
/*!
* \internal
- * \brief Determine where in the dialplan a call should go
- *
- * \details This uses the username in the request URI to try to match
- * an extension in an endpoint's context in order to route the call.
- *
- * \param rdata The SIP request
- * \param context The context to use
- * \param exten The extension to use
- */
-static enum pjsip_status_code get_destination(const pjsip_rx_data *rdata, const char *context, char *exten)
-{
- pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
- pjsip_sip_uri *sip_ruri;
-
- if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
- return PJSIP_SC_UNSUPPORTED_URI_SCHEME;
- }
-
- sip_ruri = pjsip_uri_get_uri(ruri);
- ast_copy_pj_str(exten, &sip_ruri->user, MAX_EXTEN_SIZE);
-
- if (ast_exists_extension(NULL, context, exten, 1, NULL)) {
- return PJSIP_SC_OK;
- }
- return PJSIP_SC_NOT_FOUND;
-}
-
-/*!
- * \internal
* \brief Checks to make sure the request has the correct content type.
*
* \details This module supports the following media types: "text/plain".
@@ -244,7 +214,6 @@ static void update_from(pjsip_tx_data *tdata, char *from)
PJSIP_PARSE_URI_AS_NAMEADDR))) {
pjsip_name_addr *parsed_name_addr = (pjsip_name_addr *)parsed;
pjsip_sip_uri *parsed_uri = pjsip_uri_get_uri(parsed_name_addr->uri);
-
if (pj_strlen(&parsed_name_addr->display)) {
pj_strdup(tdata->pool, &name_addr->display,
&parsed_name_addr->display);
@@ -458,58 +427,62 @@ static char *sip_to_pjsip(char *buf, int size, int capacity)
*/
static enum pjsip_status_code rx_data_to_ast_msg(pjsip_rx_data *rdata, struct ast_msg *msg)
{
-
-#define CHECK_RES(z_) do { if (z_) { ast_msg_destroy(msg); \
- return PJSIP_SC_INTERNAL_SERVER_ERROR; } } while (0)
-
- int size;
- char buf[MAX_BODY_SIZE];
+ struct ast_sip_endpoint *endpt = ast_pjsip_rdata_get_endpoint(rdata);
+ pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
+ pjsip_sip_uri *sip_ruri;
pjsip_name_addr *name_addr;
+ char buf[MAX_BODY_SIZE];
const char *field;
- pjsip_status_code code;
- struct ast_sip_endpoint *endpt = ast_pjsip_rdata_get_endpoint(rdata);
const char *context = S_OR(endpt->message_context, endpt->context);
+ char exten[AST_MAX_EXTENSION];
+ int res = 0;
+ int size;
- /* make sure there is an appropriate context and extension*/
- if ((code = get_destination(rdata, context, buf)) != PJSIP_SC_OK) {
- return code;
+ if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
+ return PJSIP_SC_UNSUPPORTED_URI_SCHEME;
}
- CHECK_RES(ast_msg_set_context(msg, "%s", context));
- CHECK_RES(ast_msg_set_exten(msg, "%s", buf));
+ sip_ruri = pjsip_uri_get_uri(ruri);
+ ast_copy_pj_str(exten, &sip_ruri->user, AST_MAX_EXTENSION);
+
+ res |= ast_msg_set_context(msg, "%s", context);
+ res |= ast_msg_set_exten(msg, "%s", exten);
/* to header */
name_addr = (pjsip_name_addr *)rdata->msg_info.to->uri;
- if ((size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf)-1)) > 0) {
- buf[size] = '\0';
- /* prepend the tech */
- CHECK_RES(ast_msg_set_to(msg, "%s", sip_to_pjsip(buf, ++size, sizeof(buf)-1)));
+ size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf) - 1);
+ if (size <= 0) {
+ return PJSIP_SC_INTERNAL_SERVER_ERROR;
}
+ buf[size] = '\0';
+ res |= ast_msg_set_to(msg, "%s", sip_to_pjsip(buf, ++size, sizeof(buf) - 1));
/* from header */
name_addr = (pjsip_name_addr *)rdata->msg_info.from->uri;
- if ((size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf)-1)) > 0) {
- buf[size] = '\0';
- CHECK_RES(ast_msg_set_from(msg, "%s", buf));
+ size = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, name_addr, buf, sizeof(buf) - 1);
+ if (size <= 0) {
+ return PJSIP_SC_INTERNAL_SERVER_ERROR;
}
+ buf[size] = '\0';
+ res |= ast_msg_set_from(msg, "%s", buf);
- /* receive address */
- field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf)-1, 1);
- CHECK_RES(ast_msg_set_var(msg, "PJSIP_RECVADDR", field));
+ field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf) - 1, 1);
+ res |= ast_msg_set_var(msg, "PJSIP_RECVADDR", field);
- /* body */
if (print_body(rdata, buf, sizeof(buf) - 1) > 0) {
- CHECK_RES(ast_msg_set_body(msg, "%s", buf));
+ res |= ast_msg_set_body(msg, "%s", buf);
}
/* endpoint name */
+ res |= ast_msg_set_tech(msg, "%s", "PJSIP");
+ res |= ast_msg_set_endpoint(msg, "%s", ast_sorcery_object_get_id(endpt));
if (endpt->id.self.name.valid) {
- CHECK_RES(ast_msg_set_var(msg, "PJSIP_PEERNAME", endpt->id.self.name.str));
+ res |= ast_msg_set_var(msg, "PJSIP_ENDPOINT", endpt->id.self.name.str);
}
- CHECK_RES(headers_to_vars(rdata, msg));
+ res |= headers_to_vars(rdata, msg);
- return PJSIP_SC_OK;
+ return !res ? PJSIP_SC_OK : PJSIP_SC_INTERNAL_SERVER_ERROR;
}
struct msg_data {
@@ -547,17 +520,14 @@ static struct msg_data* msg_data_create(const struct ast_msg *msg, const char *t
return NULL;
}
- /* if there is another sip in the uri then we are good,
- otherwise it needs a sip: in front */
- mdata->to = to == skip_sip(to) ? ast_strdup(to - 3) :
- ast_strdup(++to);
+ /* Make sure we start with sip: */
+ mdata->to = ast_begins_with(to, "sip:") ? ast_strdup(++to) : ast_strdup(to - 3);
mdata->from = ast_strdup(from);
/* sometimes from can still contain the tag at this point, so remove it */
if ((tag = strchr(mdata->from, ';'))) {
*tag = '\0';
}
-
return mdata;
}
@@ -577,8 +547,8 @@ static int msg_send(void *data)
mdata->to, &uri), ao2_cleanup);
if (!endpoint) {
- ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not find endpoint and "
- "no default outbound endpoint configured\n");
+ ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not find endpoint '%s' and "
+ "no default outbound endpoint configured\n", mdata->to);
return -1;
}
@@ -598,6 +568,9 @@ static int msg_send(void *data)
vars_to_headers(mdata->msg, tdata);
+ ast_debug(1, "Sending message to '%s' (via endpoint %s) from '%s'\n",
+ mdata->to, ast_sorcery_object_get_id(endpoint), mdata->from);
+
if (ast_sip_send_request(tdata, NULL, endpoint, NULL, NULL)) {
ast_log(LOG_ERROR, "PJSIP MESSAGE - Could not send request\n");
return -1;
@@ -670,24 +643,36 @@ static pj_bool_t module_on_rx_request(pjsip_rx_data *rdata)
return PJ_FALSE;
}
+ code = check_content_type(rdata);
+ if (code != PJSIP_SC_OK) {
+ send_response(rdata, code, NULL, NULL);
+ return PJ_TRUE;
+ }
+
msg = ast_msg_alloc();
if (!msg) {
send_response(rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL);
return PJ_TRUE;
}
- if ((code = check_content_type(rdata)) != PJSIP_SC_OK) {
+ code = rx_data_to_ast_msg(rdata, msg);
+ if (code != PJSIP_SC_OK) {
send_response(rdata, code, NULL, NULL);
+ ast_msg_destroy(msg);
return PJ_TRUE;
}
- if ((code = rx_data_to_ast_msg(rdata, msg)) == PJSIP_SC_OK) {
- /* send it to the dialplan */
- ast_msg_queue(msg);
- code = PJSIP_SC_ACCEPTED;
+ if (!ast_msg_has_destination(msg)) {
+ ast_debug(1, "MESSAGE request received, but no handler wanted it\n");
+ send_response(rdata, PJSIP_SC_NOT_FOUND, NULL, NULL);
+ ast_msg_destroy(msg);
+ return PJ_TRUE;
}
- send_response(rdata, code, NULL, NULL);
+ /* send it to the messaging core */
+ ast_msg_queue(msg);
+ send_response(rdata, PJSIP_SC_ACCEPTED, NULL, NULL);
+
return PJ_TRUE;
}