[asterisk-commits] kharwell: branch kharwell/pimp_my_sip r382479 - /team/kharwell/pimp_my_sip/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 5 18:09:34 CST 2013
Author: kharwell
Date: Tue Mar 5 18:09:31 2013
New Revision: 382479
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382479
Log:
untested - added in dialog messaging. Also cleaned up some of the out of dialog messaging code
Modified:
team/kharwell/pimp_my_sip/res/res_sip_messaging.c
team/kharwell/pimp_my_sip/res/res_sip_session.c
Modified: team/kharwell/pimp_my_sip/res/res_sip_messaging.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/res/res_sip_messaging.c?view=diff&rev=382479&r1=382478&r2=382479
==============================================================================
--- team/kharwell/pimp_my_sip/res/res_sip_messaging.c (original)
+++ team/kharwell/pimp_my_sip/res/res_sip_messaging.c Tue Mar 5 18:09:31 2013
@@ -26,26 +26,156 @@
#undef bzero
#define bzero bzero
-/* #include "pjsip/sip_uri.h" */
#include "pjsua-lib/pjsua.h"
-#include "asterisk/res_sip.h"
#include "asterisk/message.h"
#include "asterisk/module.h"
-
-/* static int validate_uri() */
-/* { */
-/* to_uri = ast_strdupa(to); */
-/* to_uri = get_in_brackets(to_uri); */
-/* parse_uri(to_uri, "sip:,sips:", &to_user, NULL, &to_host, NULL); */
-
-/* if (ast_strlen_zero(to_host)) { */
-/* ast_log(LOG_WARNING, "MESSAGE(to) is invalid for SIP - '%s'\n", to); */
-/* dialog_unlink_all(pvt); */
-/* dialog_unref(pvt, "MESSAGE(to) is invalid for SIP"); */
-/* return -1; */
-/* } */
-/* } */
+#include "asterisk/pbx.h"
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+
+static const int MAX_HDR_SIZE = 512;
+static const int MAX_BODY_SIZE = 1024;
+static const int MAX_EXTEN_SIZE = 256;
+
+/*! \brief Check to see if the given header type was already handled. */
+static int header_handled(pjsip_hdr_e type)
+{
+ return type == PJSIP_H_TO || type == PJSIP_H_FROM ||
+ type == PJSIP_H_CONTACT;
+}
+
+/*!
+ * \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(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;
+}
+
+/*!
+ * \brief Checks to make sure the request has the correct content type.
+ *
+ * \details This module supports the following media types: "text/plain".
+ * Return unsupported otherwise.
+ *
+ * \param rdata The SIP request
+ */
+static enum pjsip_status_code check_content_type(pjsip_rx_data *rdata)
+{
+ if (pj_strcmp2(&rdata->msg_info.msg->body->content_type.type, "text") ||
+ pj_strcmp2(&rdata->msg_info.msg->body->content_type.subtype, "plain")) {
+ return PJSIP_SC_UNSUPPORTED_MEDIA_TYPE;
+ }
+ return PJSIP_SC_OK;
+}
+
+/*!
+ * \brief Copies any other request header data over to ast_msg structure.
+ *
+ * \param rdata The SIP request
+ * \param msg The msg structure to copy headers into
+ */
+static int headers_to_vars(pjsip_rx_data *rdata, struct ast_msg *msg)
+{
+ char buf[MAX_HDR_SIZE];
+ int res = 0;
+ pjsip_hdr *h = rdata->msg_info.msg->hdr.next;
+ pjsip_hdr *end= &rdata->msg_info.msg->hdr;
+
+ while (h != end) {
+ if (!header_handled(h->type)) {
+ pjsip_hdr_print_on(h, buf, sizeof(buf)-1);
+ if ((res = ast_msg_set_var(msg, pj_strbuf(&h->name), buf)) != 0) {
+ break;
+ }
+ }
+ h = h->next;
+ }
+ return res;
+}
+
+/*!
+ * \brief Converts a pjsip_rx_data structure to an ast_msg structure.
+ *
+ * \details Attempts to fill in as much information as possible into the given
+ * msg structure copied from the given request data.
+ *
+ * \param rdata The SIP request
+ * \param msg The asterisk message structure to fill in.
+ */
+static enum pjsip_status_code rx_data_to_ast_msg(pjsip_rx_data *rdata, struct ast_msg *msg)
+{
+ int res;
+ char buf[MAX_BODY_SIZE];
+ pjsip_uri *uri;
+ char *field;
+ pjsip_status_code code;
+ struct ast_sip_endpoint *endpt = ast_pjsip_rdata_get_endpoint(rdata);
+
+ /* make sure there is an appropriate context and extension*/
+ if ((code = get_destination(rdata, endpt->context, buf)) != PJSIP_SC_OK) {
+ return code;
+ }
+
+ res = ast_msg_set_context(msg, "%s", endpt->context);
+ res |= ast_msg_set_exten(msg, "%s", buf);
+
+ /* to header */
+ uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
+ pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, uri, buf, sizeof(buf)-1);
+ res = ast_msg_set_to(msg, "%s", buf);
+
+ /* from header */
+ uri = pjsip_uri_get_uri(rdata->msg_info.from->uri);
+ pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, uri, buf, sizeof(buf)-1);
+ /* /todo check to see if name is in front */
+ res |= ast_msg_set_from(msg, "<%s>", buf);
+
+ /* contact header */
+ field = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
+ res |= ast_msg_set_var(msg, "SIP_FULLCONTACT", field);
+
+ /* receive address */
+ field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf)-1, 1);
+ res |= ast_msg_set_var(msg, "SIP_RECVADDR", field);
+
+ /* body */
+ rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, buf, sizeof(buf)-1);
+ res |= ast_msg_set_body(msg, "%s", buf);
+
+ res |= headers_to_vars(rdata, msg);
+
+ if (res) {
+ ast_msg_destroy(msg);
+ return PJSIP_SC_INTERNAL_SERVER_ERROR;
+ }
+ return PJSIP_SC_OK;
+
+ /* if (!ast_strlen_zero(p->peername)) { */
+ /* res |= ast_msg_set_var(msg, "SIP_PEERNAME", p->peername); */
+ /* } */
+}
/*!
* \internal
@@ -58,63 +188,63 @@
*
* \retval TRUE if the given header is blocked.
*/
-static int is_msg_header_blocked(const char *name)
-{
- int i;
-
- /*
- * Don't block Content-Type or Max-Forwards headers because the
- * user can override them.
- */
- static const char *hdr[] = {
- "To",
- "From",
- "Via",
- "Route",
- "Contact",
- "Call-ID",
- "CSeq",
- "Allow",
- "Content-Length",
- "Request-URI",
- };
-
- for (i = 0; i < ARRAY_LEN(hdr); ++i) {
- if (!strcasecmp(name, hdr[i])) {
- /* Block addition of this header. */
- return 1;
- }
- }
- return 0;
-}
-
-static void copy_headers_ast(pjsip_tx_data *tdata, const struct ast_msg *msg)
-{
- const char *name;
- const char *value;
-
- struct ast_msg_var_iterator *i = ast_msg_var_iterator_init(msg);
- while (ast_msg_var_iterator_next(msg, i, &name, &value)) {
- ast_msg_var_unref_current(i);
- if (!strcasecmp(name, "Max-Forwards")) {
- /* Decrement Max-Forwards for SIP loop prevention. */
- /* if (sscanf(value, "%30d", &pvt->maxforwards) != 1 || pvt->maxforwards < 1) { */
- /* sip_pvt_unlock(pvt); */
- /* dialog_unlink_all(pvt); */
- /* dialog_unref(pvt, "MESSAGE(Max-Forwards) reached zero."); */
- /* ast_log(LOG_NOTICE, */
- /* "MESSAGE(Max-Forwards) reached zero. MESSAGE not sent.\n"); */
- /* return -1; */
- /* } */
- /* --pvt->maxforwards; */
- }
- else if (!is_msg_header_blocked(name)) {
- ast_sip_add_header(tdata, name, value);
- }
-
- }
- ast_msg_var_iterator_destroy(i);
-}
+/* static int is_msg_header_blocked(const char *name) */
+/* { */
+/* int i; */
+
+/* /\* */
+/* * Don't block Content-Type or Max-Forwards headers because the */
+/* * user can override them. */
+/* *\/ */
+/* static const char *hdr[] = { */
+/* "To", */
+/* "From", */
+/* "Via", */
+/* "Route", */
+/* "Contact", */
+/* "Call-ID", */
+/* "CSeq", */
+/* "Allow", */
+/* "Content-Length", */
+/* "Request-URI", */
+/* }; */
+
+/* for (i = 0; i < ARRAY_LEN(hdr); ++i) { */
+/* if (!strcasecmp(name, hdr[i])) { */
+/* /\* Block addition of this header. *\/ */
+/* return 1; */
+/* } */
+/* } */
+/* return 0; */
+/* } */
+
+/* static void copy_headers_ast(pjsip_tx_data *tdata, const struct ast_msg *msg) */
+/* { */
+/* const char *name; */
+/* const char *value; */
+
+/* struct ast_msg_var_iterator *i = ast_msg_var_iterator_init(msg); */
+/* while (ast_msg_var_iterator_next(msg, i, &name, &value)) { */
+/* ast_msg_var_unref_current(i); */
+/* if (!strcasecmp(name, "Max-Forwards")) { */
+/* /\* Decrement Max-Forwards for SIP loop prevention. *\/ */
+/* /\* if (sscanf(value, "%30d", &pvt->maxforwards) != 1 || pvt->maxforwards < 1) { *\/ */
+/* /\* sip_pvt_unlock(pvt); *\/ */
+/* /\* dialog_unlink_all(pvt); *\/ */
+/* /\* dialog_unref(pvt, "MESSAGE(Max-Forwards) reached zero."); *\/ */
+/* /\* ast_log(LOG_NOTICE, *\/ */
+/* /\* "MESSAGE(Max-Forwards) reached zero. MESSAGE not sent.\n"); *\/ */
+/* /\* return -1; *\/ */
+/* /\* } *\/ */
+/* /\* --pvt->maxforwards; *\/ */
+/* } */
+/* else if (!is_msg_header_blocked(name)) { */
+/* ast_sip_add_header(tdata, name, value); */
+/* } */
+
+/* } */
+/* ast_msg_var_iterator_destroy(i); */
+/* } */
/* static void copy_headers_pjsip(pjsip_tx_data *tdata, const pjsip_msg *msg) */
/* { */
@@ -186,42 +316,21 @@
pj_str_t from = pj_str(mdata->from);
pj_str_t body = pj_str((char*)ast_msg_get_body(mdata->msg));
- status = pjsip_endpt_create_request(ep, &pjsip_message_method,
- &to, /* target uri */
- &from, /* URL to put in From header */
- &to, /* URL to put in To header */
- NULL, /* Contact header value*/
- NULL, /* use random callid */
- -1, /* use random CSeq */
- &body, /*pj_str(ast_msg_get_body(msg)), */
- &tdata); /* pointer to receive transmit data */
+ status = pjsip_endpt_create_request(ep, &pjsip_message_method, &to,
+ &from, &to, NULL, NULL, -1, &body,
+ &tdata);
if (status != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Unable to create request - %d\n", status);
return status;
}
- /* add an accept header */
- /* pjsip_msg_add_hdr(data->msg, */
- /* (pjsip_hdr*)pjsua_im_create_accept(data->pool)); */
-
- /* tdata->msg->body = pjsip_msg_body_create(tdata->pool, "text", "plain", */
- /* pj_str(ast_msg_get_body(msg))); */
-
- /* if (!tdata->msg->body) { */
- /* ast_log(LOG_ERROR, "Unable to create message body\n") */
- /* return PJ_ENOMEM; */
- /* } */
-
- /* copy_headers_ast(tdata, mdata->msg); */
-
status = pjsip_endpt_send_request(ep, tdata, -1, NULL, NULL);
if (status != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Unable to send request - %d\n", status);
return status;
}
-
return PJ_SUCCESS;
}
@@ -229,19 +338,6 @@
{
RAII_VAR(struct msg_data *, mdata, data, ao2_cleanup);
- /* struct ast_sip_body body = { */
- /* .type = "text", */
- /* .subtype = "plain", */
- /* .body_text = ast_msg_get_body(mdata->msg) */
- /* }; */
-
- /* /\* /todo - get pjsip_dialog *dlg or ast_sip_endpoint *\/ */
- /* status = ast_sip_send_request("MESSAGE", &body, NULL, NULL); */
- /* if (status != PJ_SUCCESS) { */
- /* ast_log(LOG_ERROR, "Could not send message request"); */
- /* return status; */
- /* } */
-
return sip_send_request(mdata);
}
@@ -257,107 +353,11 @@
.msg_send = sip_msg_send,
};
-/* static pj_bool_t module_start(void) */
-/* { */
-/* return PJ_SUCCESS; */
-/* } */
-
-/* static pj_bool_t module_stop(void) */
-/* { */
-/* return PJ_SUCCESS; */
-/* } */
-
-static pj_status_t send_response(pjsip_rx_data *rdata, int code);
-
-static int queue_msg(pjsip_rx_data *rdata)
-{
- int res, i;
- char buf[256];
- pjsip_uri *uri;
- char *field;
-
- struct ast_sip_endpoint *endpt = ast_pjsip_rdata_get_endpoint(rdata);
- struct ast_msg *msg = ast_msg_alloc();
-
- if (!msg) {
- send_response(rdata, 500);
- return PJ_FALSE;
- }
-
- /* to header */
- uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
- pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, uri, buf, sizeof(buf)-1);
- res = ast_msg_set_to(msg, "%s", buf);
-
- /* from header */
- uri = pjsip_uri_get_uri(rdata->msg_info.from->uri);
- pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, uri, buf, sizeof(buf)-1);
- res |= ast_msg_set_from(msg, "%s", buf);
-
- /* contact header */
- field = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
- res |= ast_msg_set_var(msg, "SIP_FULLCONTACT", field);
-
- /* receive address */
- field = pj_sockaddr_print(&rdata->pkt_info.src_addr, buf, sizeof(buf)-1, 1);
- res |= ast_msg_set_var(msg, "SIP_RECVADDR", field);
-
- /* body - remove any trailing line feeds */
- rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, buf, sizeof(buf)-1);
- for (i = strlen(buf); i > 0; --i) {
- if (buf[i] != '\n') {
- buf[i] = '\0';
- break;
- }
- }
- res |= ast_msg_set_body(msg, "%s", buf);
-
- /* extension */
- /* uri = 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 SIP_GET_DEST_UNSUPPORTED_URI; */
- /* } */
- /* sip_ruri = pjsip_uri_get_uri(ruri); */
- /* ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten)); */
- /* if (ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) { */
- /* return SIP_GET_DEST_EXTEN_FOUND; */
- /* } */
-
- /* context */
- res |= ast_msg_set_context(msg, "%s", endpt->context);
-
- if (res) {
- ast_msg_destroy(msg);
- send_response(rdata, 500);
- return PJ_FALSE;
- }
-
- ast_msg_queue(msg);
- return PJ_TRUE;
-
- /* if (!ast_strlen_zero(p->peername)) { */
- /* res |= ast_msg_set_var(msg, "SIP_PEERNAME", p->peername); */
- /* } */
-
- /* res |= ast_msg_set_exten(msg, "%s", p->exten); */
- /* res |= set_message_vars_from_req(msg, req); */
-
- /* if (res) { */
- /* ast_msg_destroy(msg); */
- /* transmit_response(p, "500 Internal Server Error", req); */
- /* } else { */
- /* ast_msg_queue(msg); */
- /* transmit_response(p, "202 Accepted", req); */
- /* } */
-}
-
-static pj_status_t send_response(pjsip_rx_data *rdata, int code)
+static pj_status_t send_response(pjsip_rx_data *rdata, enum pjsip_status_code code,
+ pjsip_dialog *dlg, pjsip_transaction *tsx)
{
pjsip_tx_data *tdata;
pj_status_t status;
- pjsip_dialog *dlg;
- pjsip_transaction *trans;
pjsip_response_addr res_addr;
pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
@@ -368,11 +368,8 @@
return status;
}
- dlg = pjsip_rdata_get_dlg(rdata);
- trans = pjsip_rdata_get_tsx(rdata);
-
- if (dlg && trans) {
- status = pjsip_dlg_send_response(dlg, trans, tdata);
+ if (dlg && tsx) {
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
} else {
/* Get where to send request. */
status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
@@ -385,53 +382,81 @@
if (status != PJ_SUCCESS) {
ast_log(LOG_ERROR, "Unable to send response (%d)", status);
- return status;
- }
-
- return PJ_TRUE;
+ }
+
+ return status;
}
static pj_bool_t module_on_rx_request(pjsip_rx_data *rdata)
{
+ enum pjsip_status_code code;
+ struct ast_msg *msg;
+
+ /* if not a MESSAGE, don't handle */
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_message_method)) {
return PJ_FALSE;
}
- /* if (pj_strcmp2(rdata->msg_info.msg->body.content_type.type, "text") || */
- /* pj_strcmp2(rdata->msg_info.msg->body.content_type.subtype, "plain")) { */
- /* send_response(rdata, 415); */
- if (queue_msg(rdata)) {
- send_response(rdata, 202);
- }
-
+ 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) {
+ send_response(rdata, code, NULL, NULL);
+ 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;
+ }
+
+ send_response(rdata, code, NULL, NULL);
return PJ_TRUE;
}
-/* static pj_bool_t module_on_rx_response(pjsip_rx_data *rdata) */
-/* { */
-/* return PJ_FALSE; */
-/* } */
-
-static pj_bool_t module_on_tx_request(pjsip_tx_data *tdata)
-{
- return PJ_SUCCESS;
-}
-
-/* static pj_bool_t module_on_tx_response(pjsip_tx_data *tdata) */
-/* { */
-/* return PJ_SUCCESS; */
-/* } */
+static int incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+ char buf[MAX_BODY_SIZE];
+ enum pjsip_status_code code;
+ struct ast_frame f;
+
+ pjsip_dialog *dlg = session->inv_session->dlg;
+ pjsip_transaction *tsx = session->inv_session->invite_tsx;
+
+ if ((code = check_content_type(rdata)) != PJSIP_SC_OK) {
+ send_response(rdata, code, dlg, tsx);
+ return 0;
+ }
+
+ rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, buf, sizeof(buf)-1);
+
+ memset(&f, 0, sizeof(f));
+ f.frametype = AST_FRAME_TEXT;
+ f.subclass.integer = 0;
+ f.offset = 0;
+ f.data.ptr = buf;
+ f.datalen = strlen(buf) + 1;
+ ast_queue_frame(session->channel, &f);
+
+ send_response(rdata, PJSIP_SC_ACCEPTED, dlg, tsx);
+ return 0;
+}
+
+static struct ast_sip_session_supplement messaging_supplement = {
+ .method = "MESSAGE",
+ .incoming_request = incoming_request
+ /* .outgoing_request = outgoing_request */
+};
static pjsip_module messaging_module = {
.name = {"Messaging Module", 16},
.id = -1,
.priority = PJSIP_MOD_PRIORITY_APPLICATION,
- /* .start = module_start, */
- /* .stop = module_stop, */
.on_rx_request = module_on_rx_request,
- /* .on_rx_response = module_on_rx_response, */
- .on_tx_request = module_on_tx_request,
- /* .on_tx_response = module_on_tx_response, */
};
static int load_module(void)
@@ -452,15 +477,15 @@
return AST_MODULE_LOAD_FAILURE;
}
+ ast_sip_session_register_supplement(&messaging_supplement);
return AST_MODULE_LOAD_SUCCESS;
}
static int unload_module(void)
{
+ ast_sip_session_unregister_supplement(&messaging_supplement);
ast_msg_tech_unregister(&msg_tech);
-
ast_sip_unregister_service(&messaging_module);
-
return 0;
}
Modified: team/kharwell/pimp_my_sip/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/res/res_sip_session.c?view=diff&rev=382479&r1=382478&r2=382479
==============================================================================
--- team/kharwell/pimp_my_sip/res/res_sip_session.c (original)
+++ team/kharwell/pimp_my_sip/res/res_sip_session.c Tue Mar 5 18:09:31 2013
@@ -28,6 +28,7 @@
#include "pjsip.h"
#include "pjsip_ua.h"
#include "pjlib.h"
+#include "pjsua-lib/pjsua.h"
#include "asterisk/res_sip_session.h"
#include "asterisk/datastore.h"
@@ -848,6 +849,11 @@
{
pj_status_t handled = PJ_FALSE;
pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
+
+ /* handle in dialog MESSAGE */
+ if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_message_method) && dlg) {
+ return PJ_TRUE;
+ }
switch (rdata->msg_info.msg->line.req.method.id) {
case PJSIP_INVITE_METHOD:
More information about the asterisk-commits
mailing list