<p>sungtae kim has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10715">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res/res_pjsip_sip_message: added sip message event notifier<br><br>This module is sending an event messages for a given channel's SIP<br>messages.<br><br>ASTERISK-28183<br><br>Change-Id: I1dedcc678265ebb74d35e7a2f58bc4b5084bcfe1<br>---<br>A res/res_pjsip_sip_message.c<br>1 file changed, 464 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/15/10715/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_pjsip_sip_message.c b/res/res_pjsip_sip_message.c</span><br><span>new file mode 100644</span><br><span>index 0000000..7ec7337</span><br><span>--- /dev/null</span><br><span>+++ b/res/res_pjsip_sip_message.c</span><br><span>@@ -0,0 +1,464 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2018, Sungtae Kim</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Sungtae Kim <pchero21@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(120, 100%, 40%);">+ * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(120, 100%, 40%);">+ * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(120, 100%, 40%);">+ * channels for your use.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the top of the source tree.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** MODULEINFO</span><br><span style="color: hsl(120, 100%, 40%);">+      <depend>pjproject</depend></span><br><span style="color: hsl(120, 100%, 40%);">+        <depend>res_pjsip</depend></span><br><span style="color: hsl(120, 100%, 40%);">+        <support_level>core</support_level></span><br><span style="color: hsl(120, 100%, 40%);">+ ***/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <pjlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <pjsip.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <pjsua.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/astobj2.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/stasis.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/stasis_app.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/logger.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/res_pjsip.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/res_pjsip_session.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "res_pjsip/include/res_pjsip_private.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define DEF_MESSAGE_NAME      "ChannelSipMessage"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int incoming_request_handler(struct ast_sip_session* session, pjsip_rx_data* rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+static void incoming_response_handler(struct ast_sip_session* session, pjsip_rx_data* rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+static void outgoing_request_handler(struct ast_sip_session* session, pjsip_tx_data* tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+static void outgoing_response_handler(struct ast_sip_session* session, pjsip_tx_data* tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void incoming_msg_handler(const char* direction, struct ast_sip_session* session, pjsip_rx_data* rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+static void outgoing_msg_handler(const char* direction, struct ast_sip_session* session, pjsip_tx_data* tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void publish_event(struct ast_sip_session* session, struct ast_json *j_evt);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static char* get_rx_request_method(pjsip_rx_data* rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+static char* get_tx_request_method(pjsip_tx_data* tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct stasis_message_type *pjsip_sip_message_type(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_json *sip_message_to_json(</span><br><span style="color: hsl(120, 100%, 40%);">+       struct stasis_message *message,</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct stasis_message_sanitizer *sanitize);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_json *blob_to_json(</span><br><span style="color: hsl(120, 100%, 40%);">+    struct stasis_message *message,</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *type,</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct stasis_message_sanitizer *sanitize);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sip_session_supplement supp_sip_in_req = {</span><br><span style="color: hsl(120, 100%, 40%);">+           .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1,</span><br><span style="color: hsl(120, 100%, 40%);">+          .incoming_request = incoming_request_handler,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sip_session_supplement supp_sip_in_res = {</span><br><span style="color: hsl(120, 100%, 40%);">+             .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1,</span><br><span style="color: hsl(120, 100%, 40%);">+          .incoming_response = incoming_response_handler,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sip_session_supplement supp_sip_out_req = {</span><br><span style="color: hsl(120, 100%, 40%);">+          .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1,</span><br><span style="color: hsl(120, 100%, 40%);">+          .outgoing_request = outgoing_request_handler,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sip_session_supplement supp_sip_out_res = {</span><br><span style="color: hsl(120, 100%, 40%);">+            .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1,</span><br><span style="color: hsl(120, 100%, 40%);">+          .outgoing_response = outgoing_response_handler,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+STASIS_MESSAGE_TYPE_DEFN(pjsip_sip_message_type,</span><br><span style="color: hsl(120, 100%, 40%);">+     .to_json = sip_message_to_json,</span><br><span style="color: hsl(120, 100%, 40%);">+       );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_json *sip_message_to_json(</span><br><span style="color: hsl(120, 100%, 40%);">+  struct stasis_message *message,</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct stasis_message_sanitizer *sanitize)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return blob_to_json(message, DEF_MESSAGE_NAME, sanitize);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_json *blob_to_json(</span><br><span style="color: hsl(120, 100%, 40%);">+ struct stasis_message *message,</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *type,</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct stasis_message_sanitizer *sanitize)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_json *to_json;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct ast_channel_blob *channel_blob = stasis_message_data(message);</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_json *blob = channel_blob->blob;</span><br><span style="color: hsl(120, 100%, 40%);">+        const struct timeval *tv = stasis_message_timestamp(message);</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        to_json = ast_json_copy(blob);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!to_json) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   res |= ast_json_object_set(to_json, "type", ast_json_string_create(type));</span><br><span style="color: hsl(120, 100%, 40%);">+  res |= ast_json_object_set(to_json, "timestamp",</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_json_timeval(*tv, NULL));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (res != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_json_unref(to_json);</span><br><span style="color: hsl(120, 100%, 40%);">+              return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return to_json;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * outgoing request sip message handler</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param session</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param tdata</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void outgoing_request_handler(struct ast_sip_session *session, pjsip_tx_data *tdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((!session) || (!tdata)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_WARNING, "Wrong input parameters.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check message type. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (tdata->msg->type != PJSIP_REQUEST_MSG) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_log(LOG_ERROR, "Wrong message type. It should not reach to here.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   outgoing_msg_handler("outgoing request", session, tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * outgoing response sip message handler</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param session</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param tdata</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void outgoing_response_handler(struct ast_sip_session *session, pjsip_tx_data *tdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((!session) || (!tdata)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_WARNING, "Wrong input parameters.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check message type. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (tdata->msg->type != PJSIP_RESPONSE_MSG) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_ERROR, "Wrong message type. It should not reach to here.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   outgoing_msg_handler("outgoing response", session, tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * incoming request sip message handler</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param session</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param tdata</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int incoming_request_handler(struct ast_sip_session *session, pjsip_rx_data *rdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((session == NULL) || (rdata == NULL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_WARNING, "Wrong input parameters.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check message type. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rdata->msg_info.msg->type != PJSIP_REQUEST_MSG) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_ERROR, "Wrong message type. It should not reach to here.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   incoming_msg_handler("incoming request", session, rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * incoming response sip message handler</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param session</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param tdata</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void incoming_response_handler(struct ast_sip_session* session, pjsip_rx_data* rdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((session == NULL) || (rdata == NULL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_WARNING, "Wrong input parameters.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check message type. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rdata->msg_info.msg->type != PJSIP_RESPONSE_MSG) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_ERROR, "Wrong message type. It should not reach to here.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   incoming_msg_handler("incoming response", session, rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void incoming_msg_handler(const char* direction, struct ast_sip_session* session, pjsip_rx_data* rdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_channel_snapshot *snapshot;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ast_json *j_chan;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_json* j_data;</span><br><span style="color: hsl(120, 100%, 40%);">+      char* method;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((!direction) || (!session) || (!rdata)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_WARNING, "Wrong input parameters.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* for the BYE response, the channel already removed it. */</span><br><span style="color: hsl(120, 100%, 40%);">+   /* and if no channel, doesn't go futher */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!session->channel) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* get method */</span><br><span style="color: hsl(120, 100%, 40%);">+      method = get_rx_request_method(rdata);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (method == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_ERROR, "Could not get requested method name.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* create channel info */</span><br><span style="color: hsl(120, 100%, 40%);">+     snapshot = ast_channel_snapshot_create(session->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!snapshot) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_free(method);</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     j_chan = ast_channel_snapshot_to_json(snapshot, stasis_app_get_sanitizer());</span><br><span style="color: hsl(120, 100%, 40%);">+  ao2_cleanup(snapshot);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* create data */</span><br><span style="color: hsl(120, 100%, 40%);">+     j_data = ast_json_pack("{s:s, s:s, s:s, s:o}",</span><br><span style="color: hsl(120, 100%, 40%);">+                      "direction",                  direction,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "method",                             method,</span><br><span style="color: hsl(120, 100%, 40%);">+                       "raw",                                        rdata->msg_info.msg_buf,</span><br><span style="color: hsl(120, 100%, 40%);">+                   "channel",                            j_chan</span><br><span style="color: hsl(120, 100%, 40%);">+                        );</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_free(method);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* publish message */</span><br><span style="color: hsl(120, 100%, 40%);">+ publish_event(session, j_data);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_json_unref(j_data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void outgoing_msg_handler(const char *direction, struct ast_sip_session *session, pjsip_tx_data *tdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_channel_snapshot *snapshot;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ast_json *j_chan;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_json *j_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+       char *method;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((!direction) || (!session) || (!tdata)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_WARNING, "Wrong input parameters.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* check channel */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!session->channel) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* encode tx data*/</span><br><span style="color: hsl(120, 100%, 40%);">+   ret = pjsip_tx_data_encode(tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ret != PJ_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* get method */</span><br><span style="color: hsl(120, 100%, 40%);">+      method = get_tx_request_method(tdata);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (method == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_ERROR, "Could not get request method name.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* create channel info */</span><br><span style="color: hsl(120, 100%, 40%);">+     snapshot = ast_channel_snapshot_create(session->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+  j_chan = ast_channel_snapshot_to_json(snapshot, stasis_app_get_sanitizer());</span><br><span style="color: hsl(120, 100%, 40%);">+  ao2_cleanup(snapshot);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* create message */</span><br><span style="color: hsl(120, 100%, 40%);">+  j_msg = ast_json_pack("{s:s, s:s, s:s, s:o}",</span><br><span style="color: hsl(120, 100%, 40%);">+                       "direction",                  direction,</span><br><span style="color: hsl(120, 100%, 40%);">+                    "method",                             method,</span><br><span style="color: hsl(120, 100%, 40%);">+                       "raw",                                        tdata->buf.start,</span><br><span style="color: hsl(120, 100%, 40%);">+                  "channel",                            j_chan</span><br><span style="color: hsl(120, 100%, 40%);">+                        );</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_free(method);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* publish message */</span><br><span style="color: hsl(120, 100%, 40%);">+ publish_event(session, j_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_json_unref(j_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Convenience function to publish an \ref ast_foo message to the</span><br><span style="color: hsl(120, 100%, 40%);">+ * \ref foo_topic.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void publish_event(struct ast_sip_session* session, struct ast_json *j_evt)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if ((!session) || (!session->channel) || (!j_evt)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_log(LOG_WARNING, "Wrong input parameter.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* send message */</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_channel_lock(session->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_channel_publish_blob(session->channel, pjsip_sip_message_type(), j_evt);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_channel_unlock(session->channel);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns given received sip message's requested method name.\n</span><br><span style="color: hsl(120, 100%, 40%);">+ * The return string should be freed after use.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param rdata</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static char* get_rx_request_method(pjsip_rx_data* rdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       char *res;</span><br><span style="color: hsl(120, 100%, 40%);">+    const pjsip_cseq_hdr *cseq;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rdata == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_WARNING, "Wrong input parameter.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if(rdata->msg_info.msg == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_ERROR, "Could not get message info.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   cseq = (const pjsip_cseq_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CSEQ, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (cseq == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_WARNING, "Could not get cseq info.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_pj_str2(&res, &cseq->method.name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/**</span><br><span style="color: hsl(120, 100%, 40%);">+ * Returns given received sip message's requested method name.\n</span><br><span style="color: hsl(120, 100%, 40%);">+ * The return string should be freed after use.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param rdata</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static char* get_tx_request_method(pjsip_tx_data* tdata)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   char *res;</span><br><span style="color: hsl(120, 100%, 40%);">+    const pjsip_cseq_hdr *cseq;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tdata == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_WARNING, "Wrong input parameter.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if(tdata->msg == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_ERROR, "Could not get message info.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   cseq = (const pjsip_cseq_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (cseq == NULL) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_WARNING, "Could not get cseq info.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_pj_str2(&res, &cseq->method.name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static bool init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ret = STASIS_MESSAGE_TYPE_INIT(pjsip_sip_message_type);</span><br><span style="color: hsl(120, 100%, 40%);">+       if(ret != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return false;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* register callbacks */</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_sip_session_register_supplement(&supp_sip_in_req);</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sip_session_register_supplement(&supp_sip_in_res);</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sip_session_register_supplement(&supp_sip_out_req);</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_sip_session_register_supplement(&supp_sip_out_res);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_log(LOG_DEBUG, "Completed init.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return true;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void terminate(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     STASIS_MESSAGE_TYPE_CLEANUP(pjsip_sip_message_type);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int load_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ret = init();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret != true) {</span><br><span style="color: hsl(120, 100%, 40%);">+            terminate();</span><br><span style="color: hsl(120, 100%, 40%);">+          return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int unload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       terminate();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SIP Message Support",</span><br><span style="color: hsl(120, 100%, 40%);">+    .support_level = AST_MODULE_SUPPORT_CORE,</span><br><span style="color: hsl(120, 100%, 40%);">+     .load = load_module,</span><br><span style="color: hsl(120, 100%, 40%);">+  .unload = unload_module,</span><br><span style="color: hsl(120, 100%, 40%);">+      .load_pri = AST_MODPRI_APP_DEPEND,</span><br><span style="color: hsl(120, 100%, 40%);">+    .requires = "res_pjsip,res_pjsip_session",</span><br><span style="color: hsl(120, 100%, 40%);">+);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10715">change 10715</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10715"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I1dedcc678265ebb74d35e7a2f58bc4b5084bcfe1 </div>
<div style="display:none"> Gerrit-Change-Number: 10715 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: sungtae kim <pchero21@gmail.com> </div>