Explorar o código

pua_json: new module to update presence using JSON data objects

Emmanuel Schmidbauer %!s(int64=7) %!d(string=hai) anos
pai
achega
81aa7c1f56

+ 17 - 0
src/modules/pua_json/Makefile

@@ -0,0 +1,17 @@
+#
+# PUA_JSON module
+#
+#
+# WARNING: do not run this directly, it should be run by the master Makefile
+
+include ../../Makefile.defs
+
+auto_gen=
+NAME=pua_json.so
+
+LIBS=-ljson-c
+DEFS+=-I$(LOCALBASE)/include -I/usr/local/include $(shell pkg-config --cflags json-c)
+
+DEFS+=-DKAMAILIO_MOD_INTERFACE
+
+include ../../Makefile.modules

+ 0 - 0
src/modules/pua_json/README


+ 134 - 0
src/modules/pua_json/defs.h

@@ -0,0 +1,134 @@
+/*
+ * PUA_JSON module
+ *
+ * Copyright (C) 2010-2014 2600Hz
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contributor(s):
+ * 2600Hz Team
+ * Emmanuel Schmidbauer <[email protected]>
+ *
+ */
+
+#ifndef _PUA_JSON_DEFS_H_
+#define _PUA_JSON_DEFS_H_
+
+#define BLF_MAX_DIALOGS 8
+#define BLF_JSON_PRES		"Presentity"
+#define BLF_JSON_PRES_USER	"Presentity-User"
+#define BLF_JSON_PRES_REALM	"Presentity-Realm"
+#define BLF_JSON_FROM      	"From"
+#define BLF_JSON_FROM_USER 	"From-User"
+#define BLF_JSON_FROM_REALM	"From-Realm"
+#define BLF_JSON_FROM_URI	"From-URI"
+#define BLF_JSON_TO        	"To"
+#define BLF_JSON_TO_USER 	"To-User"
+#define BLF_JSON_TO_REALM	"To-Realm"
+#define BLF_JSON_TO_URI		"To-URI"
+#define BLF_JSON_CALLID    	"Call-ID"
+#define BLF_JSON_TOTAG     	"To-Tag"
+#define BLF_JSON_FROMTAG   	"From-Tag"
+#define BLF_JSON_STATE     	"State"
+#define BLF_JSON_USER      	"User"
+#define BLF_JSON_QUEUE     	"Queue"
+#define BLF_JSON_EXPIRES	"Expires"
+#define BLF_JSON_APP_NAME       "App-Name"
+#define BLF_JSON_APP_VERSION    "App-Version"
+#define BLF_JSON_NODE           "Node"
+#define BLF_JSON_SERVERID       "Server-ID"
+#define BLF_JSON_EVENT_CATEGORY "Event-Category"
+#define BLF_JSON_EVENT_NAME     "Event-Name"
+#define BLF_JSON_TYPE           "Type"
+#define BLF_JSON_MSG_ID         "Msg-ID"
+#define BLF_JSON_DIRECTION      "Direction"
+
+#define BLF_JSON_CONTACT   	"Contact"
+#define BLF_JSON_EVENT_PKG      "Event-Package"
+#define MWI_JSON_WAITING        "Messages-Waiting"
+#define MWI_JSON_VOICE_MESSAGE  "MWI-Voice-Message"
+#define MWI_JSON_NEW            "Messages-New"
+#define MWI_JSON_SAVED          "Messages-Saved"
+#define MWI_JSON_URGENT         "Messages-Urgent"
+#define MWI_JSON_URGENT_SAVED   "Messages-Urgent-Saved"
+#define MWI_JSON_ACCOUNT        "Message-Account"
+#define MWI_JSON_FROM      	"From"
+#define MWI_JSON_TO        	"To"
+
+#define TO_TAG_BUFFER_SIZE 128
+#define FROM_TAG_BUFFER_SIZE 128
+#define SENDER_BUFFER_SIZE 1024
+#define DIALOGINFO_BODY_BUFFER_SIZE 8192
+#define MWI_BODY_BUFFER_SIZE 2048
+#define PRESENCE_BODY_BUFFER_SIZE 4096
+
+#define MWI_BODY_VOICE_MESSAGE "Messages-Waiting: %.*s\r\nMessage-Account: %.*s\r\nVoice-Message: %.*s\r\n"
+#define MWI_BODY_NO_VOICE_MESSAGE "Messages-Waiting: %.*s\r\nMessage-Account: %.*s\r\n"
+#define MWI_BODY             "Messages-Waiting: %.*s\r\nMessage-Account: %.*s\r\nVoice-Message: %.*s/%.*s (%.*s/%.*s)\r\n"
+#define PRESENCE_BODY        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
+<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" xmlns:c=\"urn:ietf:params:xml:ns:pidf:cipid\" entity=\"%s\"> \
+<tuple xmlns=\"urn:ietf:params:xml:ns:pidf\" id=\"%s\">\
+<status>\
+<basic>%s</basic>\
+</status>\
+</tuple>\
+<note xmlns=\"urn:ietf:params:xml:ns:pidf\">%s</note>\
+<dm:person xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" id=\"1\">\
+<rpid:activities>%s</rpid:activities>\
+<dm:note>%s</dm:note>\
+</dm:person>\
+</presence>"
+
+#define DIALOGINFO_EMPTY_BODY "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
+<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"1\" state=\"full\" entity=\"%.*s\"> \
+<dialog call-id=\"76001e23e09704ea9e1257ebea85e1f3\" direction=\"initiator\">\
+<state>terminated</state>\
+</dialog>\
+</dialog-info>"
+
+#define LOCAL_TAG "local-tag=\"%.*s\""
+#define REMOTE_TAG "remote-tag=\"%.*s\""
+
+#define DIALOGINFO_BODY "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
+<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"1\" state=\"full\" entity=\"%.*s\">\
+<dialog id=\"%.*s\" call-id=\"%.*s\" %.*s %.*s direction=\"%.*s\">\
+<state>%.*s</state>\
+<local>\
+<identity display=\"%.*s\">%.*s</identity>\
+<target uri=\"%.*s\"/>\
+</local>\
+<remote>\
+<identity display=\"%.*s\">%.*s</identity>\
+<target uri=\"%.*s\"/>\
+</remote>\
+</dialog>\
+</dialog-info>"
+
+#define DIALOGINFO_BODY_2 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
+<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"1\" state=\"full\" entity=\"%.*s\">\
+<dialog id=\"%.*s\" call-id=\"%.*s\" %.*s %.*s direction=\"%.*s\">\
+<state>%.*s</state>\
+<local>\
+<identity display=\"%.*s\">%.*s</identity>\
+</local>\
+<remote>\
+<identity display=\"%.*s\">%.*s</identity>\
+</remote>\
+</dialog>\
+</dialog-info>"
+
+#endif /* _PUA_JSON_DEFS_H_ */

+ 4 - 0
src/modules/pua_json/doc/Makefile

@@ -0,0 +1,4 @@
+docs = json_pua.xml
+
+docbook_dir = ../../../../doc/docbook
+include $(docbook_dir)/Makefile.module

+ 37 - 0
src/modules/pua_json/doc/pua_json.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
+%docentities;
+
+]>
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+    <bookinfo>
+	<title>PUA_JSON Module</title>
+	<productname class="trade">&kamailioname;</productname>
+	<authorgroup>
+	    <author>
+		<firstname>Emmanuel Schmidbauer</firstname>
+		<email>[email protected]</email>
+	    </author>
+	    <editor>
+		<firstname>Emmanuel</firstname>
+		<surname>Schmidbauer</surname>
+		<email>[email protected]</email>
+	    </editor>
+	</authorgroup>
+	<copyright>
+	    <year>2018</year>
+	    <holder>VoIPxSWITCH</holder>
+	</copyright>
+    </bookinfo>
+    <toc></toc>
+    
+    <xi:include href="pua_json_admin.xml"/>
+    <!-- <xi:include href="db_text_devel.xml"/> -->
+    
+
+</book>

+ 105 - 0
src/modules/pua_json/doc/pua_json_admin.xml

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding='ISO-8859-1'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
+
+<!-- Include general documentation entities -->
+<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
+%docentities;
+
+]>
+<!-- Module User's Guide -->
+
+<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
+	<title>&adminguide;</title>
+
+
+	<section>
+		<title>Overview</title>
+		<para>The PUA_JSON module adds support to publish updates to the presence module through the pua_json_publish() function.
+		</para>
+		<para>
+			From a high-level perspective, the module may be used for:
+			<itemizedlist>
+				<listitem>
+					<para>
+						Providing a real-time presence updates.
+					</para>
+				</listitem>
+			</itemizedlist>
+		</para>
+
+	</section>
+	<section>
+		<title>How it works</title>
+		<para>
+			The module parses json data objects and inserts them into the presentity table for real-time presence updates.
+		</para>
+	</section>
+
+	<section>
+		<title>Dependencies</title>
+		<section>
+			<title>&kamailio; Modules</title>
+			<para>
+				The following modules must be loaded before this module:
+				<itemizedlist>
+					<listitem>
+						<para>
+							<emphasis>none</emphasis>.
+						</para>
+					</listitem>
+				</itemizedlist>
+			</para>
+		</section>
+		<section>
+			<title>External Libraries or Applications</title>
+			<para>
+				The following libraries or applications must be installed
+				<itemizedlist>
+					<listitem>
+						<para>
+							<emphasis>libjson</emphasis>.
+						</para>
+					</listitem>
+				</itemizedlist>
+			</para>
+		</section>
+	</section>
+
+	<section>
+		<title>Functions</title>
+		<section>
+			<title>
+				<function moreinfo="none">pua_json_publish(json_payload)</function>
+			</title>
+			<para>
+				The function build presentity state from json_payload and updates presentity table.
+			</para>
+			<para>
+				Usage: presence related.
+			</para>
+			<para>
+				This function can be used from ANY ROUTE.
+			</para>
+
+			<example>
+				<title><function>pua_json_publish</function> usage</title>
+<programlisting format="linespecific">
+...
+event_route[xhttp:request] {
+	$var(call-id) = $(rb{json.parse,Call-ID});
+	if ($(rb{json.parse,Event-Package}) == "dialog") {
+		xlog("L_INFO", "$var(call-id)|log|received $(rb{json.parse,Event-Package}) update for $(rb{json.parse,From})");
+		pua_json_publish($rb);
+	}
+}
+...
+</programlisting>
+			</example>
+		</section>
+
+	</section>
+
+
+</chapter>
+

+ 68 - 0
src/modules/pua_json/pua_json_mod.c

@@ -0,0 +1,68 @@
+/*
+ * PUA_JSON module interface
+ *
+ * Copyright (C) 2018 VoIPxSWITCH
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../json/api.h"
+#include "../presence/bind_presence.h"
+#include "pua_json_mod.h"
+
+MODULE_VERSION
+
+static param_export_t params[] = {
+		{"pua_include_entity", INT_PARAM, &pua_include_entity},
+		{0, 0, 0}};
+
+static cmd_export_t cmds[] = {
+		{"pua_json_publish", (cmd_function)pua_json_publish, 1, 0, 0,
+				ANY_ROUTE},
+		{0, 0, 0, 0, 0, 0}};
+
+struct module_exports exports = {
+		"pua_json", DEFAULT_DLFLAGS, /* dlopen flags */
+		cmds,						 /* Exported functions */
+		params,						 /* Exported parameters */
+		0,							 /* exported statistics */
+		0,							 /* exported MI functions */
+		0, 0,						 /* extra processes */
+		mod_init,					 /* module initialization function */
+		0,							 /* response function*/
+		0,							 /* destroy function */
+		0							 /* per-child init function */
+};
+
+static int mod_init(void)
+{
+	if(json_load_api(&json_api) < 0) {
+		LM_ERR("cannot bind to JSON API\n");
+		return -1;
+	}
+	if(presence_load_api(&presence_api) < 0) {
+		LM_ERR("cannot bind to PRESENCE API\n");
+		return -1;
+	}
+
+	return 0;
+}

+ 37 - 0
src/modules/pua_json/pua_json_mod.h

@@ -0,0 +1,37 @@
+/*
+ * PUA_JSON module interface
+ *
+ * Copyright (C) 2018 VoIPxSWITCH
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ */
+
+#ifndef __PUA_JSON_MOD_H_
+#define __PUA_JSON_MOD_H_
+
+#include "../../core/mod_fix.h"
+#include "pua_json_publish.h"
+
+json_api_t json_api;
+presence_api_t presence_api;
+int pua_include_entity = 1;
+
+static int mod_init(void);
+
+#endif

+ 389 - 0
src/modules/pua_json/pua_json_publish.c

@@ -0,0 +1,389 @@
+/*
+ * PUA_JSON module interface
+ *
+ * Copyright (C) 2010-2014 2600Hz
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contributor(s):
+ * 2600Hz Team
+ * Emmanuel Schmidbauer <[email protected]>
+ *
+ */
+
+#include <json.h>
+#include "../json/api.h"
+#include "../presence/bind_presence.h"
+
+#include "defs.h"
+#include "pua_json_publish.h"
+
+extern json_api_t json_api;
+extern presence_api_t presence_api;
+extern int pua_include_entity;
+
+str str_event_message_summary = str_init("message-summary");
+str str_event_dialog = str_init("dialog");
+str str_event_presence = str_init("presence");
+
+str str_username_col = str_init("username");
+str str_domain_col = str_init("domain");
+str str_body_col = str_init("body");
+str str_expires_col = str_init("expires");
+str str_received_time_col = str_init("received_time");
+str str_presentity_uri_col = str_init("presentity_uri");
+str str_priority_col = str_init("priority");
+
+str str_event_col = str_init("event");
+str str_contact_col = str_init("contact");
+str str_callid_col = str_init("callid");
+str str_from_tag_col = str_init("from_tag");
+str str_to_tag_col = str_init("to_tag");
+str str_etag_col = str_init("etag");
+str str_sender_col = str_init("sender");
+
+str str_presence_note_busy = str_init("Busy");
+str str_presence_note_otp = str_init("On the Phone");
+str str_presence_note_idle = str_init("Idle");
+str str_presence_note_offline = str_init("Offline");
+str str_presence_act_busy = str_init("<rpid:busy/>");
+str str_presence_act_otp = str_init("<rpid:on-the-phone/>");
+str str_presence_status_offline = str_init("closed");
+str str_presence_status_online = str_init("open");
+
+str str_null_string = str_init("NULL");
+
+int pua_json_update_presentity(str *event, str *realm, str *user, str *etag, str *sender, str *body, int expires, int new_t, int replace) {
+	int ret;
+	if(!event->len)
+	{
+		LM_ERR("presence event must be set\n");
+		return -1;
+	}
+	if (!realm->len) {	
+		LM_ERR("presence realm must be set\n");
+		return -1;
+	}
+	if (!user->len) {
+		LM_ERR("presence user must be set\n");
+		return -1;
+	}
+	if (!etag->len) {
+		LM_ERR("presence etag must be set\n");
+		return -1;
+	}
+	if (!sender->len) {
+		LM_ERR("presence sender must be set\n");
+		return -1;
+	}
+	if (!body->len) {
+		LM_ERR("presence body must be set\n");
+		return -1;
+	}
+	ret = presence_api.update_presentity(
+			event, realm, user, etag, sender, body, expires, new_t, replace);
+	return ret;
+}
+
+int pua_json_publish_presence_to_presentity(struct json_object *json_obj) {
+	int ret = 1;
+	int len;
+	str from = {0, 0};
+	str from_user = {0, 0}, to_user = {0, 0};
+	str from_realm = {0, 0};
+	str callid = {0, 0};
+	str state = {0, 0};
+	str event = str_init("presence");
+	str presence_body = {0, 0};
+	str activity = str_init("");
+	str note = str_init("Available");
+	str status = str_presence_status_online;
+	int expires = 0;
+
+	char *body = (char *)pkg_malloc(PRESENCE_BODY_BUFFER_SIZE);
+	if (body == NULL) {
+		LM_ERR("Error allocating buffer for publish\n");
+		ret = -1;
+		goto error;
+	}
+
+	json_api.extract_field(json_obj, BLF_JSON_FROM, &from);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_USER, &from_user);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_REALM, &from_realm);
+	json_api.extract_field(json_obj, BLF_JSON_TO_USER, &to_user);
+	json_api.extract_field(json_obj, BLF_JSON_CALLID, &callid);
+	json_api.extract_field(json_obj, BLF_JSON_STATE, &state);
+
+	struct json_object *ExpiresObj =  json_api.get_object(json_obj, BLF_JSON_EXPIRES);
+	if (ExpiresObj != NULL) {
+		expires = json_object_get_int(ExpiresObj);
+	}
+
+	if (!from_user.len || !to_user.len || !state.len) {
+		LM_ERR("missing one of From / To / State\n");
+		goto error;
+	}
+
+	if (!strcmp(state.s, "early")) {
+		note = str_presence_note_busy;
+		activity = str_presence_act_busy;
+
+	} else if (!strcmp(state.s, "confirmed")) {
+		note = str_presence_note_otp;
+		activity = str_presence_act_otp;
+
+	} else if (!strcmp(state.s, "offline")) {
+		note = str_presence_note_offline;
+		status = str_presence_status_offline;
+
+	}; // else {
+	//	note = str_presence_note_idle;
+	//}
+
+	len = snprintf(body, PRESENCE_BODY_BUFFER_SIZE, PRESENCE_BODY, from_user.s,
+			callid.s, status.s, note.s, activity.s, note.s);
+
+	presence_body.s = body;
+	presence_body.len = len;
+
+	pua_json_update_presentity(&event, &from_realm, &from_user, &callid, &from, &presence_body, expires, 1, 1);
+
+ error:
+
+	if(body)
+		pkg_free(body);
+
+	return ret;
+}
+
+int pua_json_publish_mwi_to_presentity(struct json_object *json_obj) {
+	int ret = 1;
+	int len;
+	str event = str_init("message-summary");
+	str from = {0, 0};
+	str from_user = {0, 0};
+	str from_realm = {0, 0};
+	str callid = {0, 0};
+	str mwi_waiting = {0, 0}, mwi_voice_message = {0, 0}, mwi_new = {0, 0}, mwi_saved = {0, 0}, mwi_urgent = {0, 0}, mwi_urgent_saved = {0, 0}, mwi_account = {0, 0}, mwi_body = {0, 0};
+	int expires = 0;
+
+	char *body = (char *)pkg_malloc(MWI_BODY_BUFFER_SIZE);
+	if(body == NULL) {
+		LM_ERR("Error allocating buffer for publish\n");
+		ret = -1;
+		goto error;
+	}
+
+	json_api.extract_field(json_obj, BLF_JSON_FROM, &from);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_USER, &from_user);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_REALM, &from_realm);
+	json_api.extract_field(json_obj, BLF_JSON_CALLID, &callid);
+
+	json_api.extract_field(json_obj, MWI_JSON_WAITING, &mwi_waiting);
+	json_api.extract_field(
+			json_obj, MWI_JSON_VOICE_MESSAGE, &mwi_voice_message);
+	json_api.extract_field(json_obj, MWI_JSON_NEW, &mwi_new);
+	json_api.extract_field(json_obj, MWI_JSON_SAVED, &mwi_saved);
+	json_api.extract_field(json_obj, MWI_JSON_URGENT, &mwi_urgent);
+	json_api.extract_field(json_obj, MWI_JSON_URGENT_SAVED, &mwi_urgent_saved);
+	json_api.extract_field(json_obj, MWI_JSON_ACCOUNT, &mwi_account);
+
+	struct json_object *ExpiresObj =
+			json_api.get_object(json_obj, BLF_JSON_EXPIRES);
+	if (ExpiresObj != NULL) {
+		expires = json_object_get_int(ExpiresObj);
+	}
+
+	if (mwi_new.len > 0) {
+		len = snprintf(body, MWI_BODY_BUFFER_SIZE, MWI_BODY, mwi_waiting.len,
+				mwi_waiting.s, mwi_account.len, mwi_account.s, mwi_new.len,
+				mwi_new.s, mwi_saved.len, mwi_saved.s, mwi_urgent.len,
+				mwi_urgent.s, mwi_urgent_saved.len, mwi_urgent_saved.s);
+	} else if (mwi_voice_message.len > 0) {
+		len = snprintf(body, MWI_BODY_BUFFER_SIZE, MWI_BODY_VOICE_MESSAGE,
+				mwi_waiting.len, mwi_waiting.s, mwi_account.len, mwi_account.s,
+				mwi_voice_message.len, mwi_voice_message.s);
+	} else {
+		len = snprintf(body, MWI_BODY_BUFFER_SIZE, MWI_BODY_NO_VOICE_MESSAGE,
+				mwi_waiting.len, mwi_waiting.s, mwi_account.len, mwi_account.s);
+	}
+
+	mwi_body.s = body;
+	mwi_body.len = len;
+
+	pua_json_update_presentity(&event, &from_realm, &from_user, &callid, &from, &mwi_body, expires, 1, 1);
+
+ error:
+
+	if(body)
+		pkg_free(body);
+
+	return ret;
+}
+
+
+int pua_json_publish_dialoginfo_to_presentity(struct json_object *json_obj) {
+	int ret = 1;
+	int len;
+	str from = {0, 0}, to = {0, 0}, pres = {0, 0};
+	str from_user = {0, 0}, to_user = {0, 0}, pres_user = {0, 0};
+	str from_realm = {0, 0}, pres_realm = {0, 0};
+	str from_uri = {0, 0}, to_uri = {0, 0};
+	str callid = {0, 0}, fromtag = {0, 0}, totag = {0, 0};
+	str state = {0, 0};
+	str direction = {0, 0};
+	char sender_buf[SENDER_BUFFER_SIZE + 1];
+	str sender = {0, 0};
+	str dialoginfo_body = {0, 0};
+	int expires = 0;
+	str event = str_init("dialog");
+	char to_tag_buffer[TO_TAG_BUFFER_SIZE + 1];
+	char from_tag_buffer[FROM_TAG_BUFFER_SIZE + 1];
+
+	char *body = (char *)pkg_malloc(DIALOGINFO_BODY_BUFFER_SIZE);
+	if(body == NULL) {
+		LM_ERR("Error allocating buffer for publish\n");
+		ret = -1;
+		goto error;
+	}
+
+	json_api.extract_field(json_obj, BLF_JSON_PRES, &pres);
+	json_api.extract_field(json_obj, BLF_JSON_PRES_USER, &pres_user);
+	json_api.extract_field(json_obj, BLF_JSON_PRES_REALM, &pres_realm);
+	json_api.extract_field(json_obj, BLF_JSON_FROM, &from);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_USER, &from_user);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_REALM, &from_realm);
+	json_api.extract_field(json_obj, BLF_JSON_FROM_URI, &from_uri);
+	json_api.extract_field(json_obj, BLF_JSON_TO, &to);
+	json_api.extract_field(json_obj, BLF_JSON_TO_USER, &to_user);
+	json_api.extract_field(json_obj, BLF_JSON_TO_URI, &to_uri);
+	json_api.extract_field(json_obj, BLF_JSON_CALLID, &callid);
+	json_api.extract_field(json_obj, BLF_JSON_FROMTAG, &fromtag);
+	json_api.extract_field(json_obj, BLF_JSON_TOTAG, &totag);
+	json_api.extract_field(json_obj, BLF_JSON_DIRECTION, &direction);
+	json_api.extract_field(json_obj, BLF_JSON_STATE, &state);
+
+	struct json_object *ExpiresObj =
+			json_api.get_object(json_obj, BLF_JSON_EXPIRES);
+	if (ExpiresObj != NULL) {
+		expires = json_object_get_int(ExpiresObj);
+	}
+
+	if (!from.len || !to.len || !state.len) {
+		LM_ERR("missing one of From / To / State\n");
+		goto error;
+	}
+
+	if (!pres.len || !pres_user.len || !pres_realm.len) {
+		pres = from;
+		pres_user = from_user;
+		pres_realm = from_realm;
+	}
+
+	if (!from_uri.len)
+		from_uri = from;
+
+	if (!to_uri.len)
+		to_uri = to;
+
+	if (fromtag.len > 0) {
+		fromtag.len = snprintf(from_tag_buffer, TO_TAG_BUFFER_SIZE, LOCAL_TAG,
+				fromtag.len, fromtag.s);
+		fromtag.s = from_tag_buffer;
+	}
+
+	if (totag.len > 0) {
+		totag.len = snprintf(to_tag_buffer, FROM_TAG_BUFFER_SIZE, REMOTE_TAG,
+				totag.len, totag.s);
+		totag.s = to_tag_buffer;
+	}
+
+	if (callid.len) {
+		if (pua_include_entity) {
+			len = snprintf(body, DIALOGINFO_BODY_BUFFER_SIZE, DIALOGINFO_BODY,
+					pres.len, pres.s, callid.len, callid.s, callid.len,
+					callid.s, fromtag.len, fromtag.s, totag.len, totag.s,
+					direction.len, direction.s, state.len, state.s,
+					from_user.len, from_user.s, from.len, from.s, from_uri.len,
+					from_uri.s, to_user.len, to_user.s, to.len, to.s,
+					to_uri.len, to_uri.s);
+		} else {
+			len = snprintf(body, DIALOGINFO_BODY_BUFFER_SIZE, DIALOGINFO_BODY_2,
+					pres.len, pres.s, callid.len, callid.s, callid.len,
+					callid.s, fromtag.len, fromtag.s, totag.len, totag.s,
+					direction.len, direction.s, state.len, state.s,
+					from_user.len, from_user.s, from.len, from.s, to_user.len,
+					to_user.s, to.len, to.s);
+		}
+	} else {
+		len = snprintf(body, DIALOGINFO_BODY_BUFFER_SIZE, DIALOGINFO_EMPTY_BODY,
+				pres.len, pres.s);
+	}
+
+	sender.len = snprintf(sender_buf, SENDER_BUFFER_SIZE, "sip:%s", callid.s);
+	sender.s = sender_buf;
+
+	dialoginfo_body.s = body;
+	dialoginfo_body.len = len;
+
+	pua_json_update_presentity(&event, &pres_realm, &pres_user, &callid, &sender, &dialoginfo_body, expires, 1, 1);
+
+ error:
+
+	if(body)
+		pkg_free(body);
+
+	return ret;
+}
+
+
+int pua_json_publish(struct sip_msg* msg, char *json) {
+	str event_name = {0, 0}, event_package = {0, 0};
+	struct json_object *json_obj = NULL;
+	int ret = 1;
+
+	/* extract info from json and construct xml */
+	json_obj = json_api.json_parse(json);
+	if (json_obj == NULL) {
+		ret = -1;
+		goto error;
+	}
+
+	json_api.extract_field(json_obj, BLF_JSON_EVENT_NAME, &event_name);
+	if (event_name.len == 6 && strncmp(event_name.s, "update", 6) == 0) {
+		json_api.extract_field(json_obj, BLF_JSON_EVENT_PKG, &event_package);
+		if (event_package.len == str_event_dialog.len
+				&& strncmp(event_package.s, str_event_dialog.s, event_package.len) == 0) {
+			ret = pua_json_publish_dialoginfo_to_presentity(
+					json_obj);
+		} else if (event_package.len == str_event_message_summary.len
+				&& strncmp(event_package.s, str_event_message_summary.s, event_package.len) == 0) {
+			ret = pua_json_publish_mwi_to_presentity(json_obj);
+		} else if (event_package.len == str_event_presence.len
+				&& strncmp(event_package.s, str_event_presence.s, event_package.len) == 0) {
+			ret = pua_json_publish_presence_to_presentity(
+					json_obj);
+		}
+	}
+
+error:
+
+	if (json_obj)
+		json_object_put(json_obj);
+
+	return ret;
+}

+ 33 - 0
src/modules/pua_json/pua_json_publish.h

@@ -0,0 +1,33 @@
+/*
+ * PUA_JSON module interface
+ *
+ * Copyright (C) 2010-2014 2600Hz
+ *
+ * This file is part of Kamailio, a free SIP server.
+ *
+ * Kamailio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * Kamailio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contributor(s):
+ * 2600Hz Team
+ * Emmanuel Schmidbauer <[email protected]>
+ *
+ */
+
+#ifndef __PUA_JSON_PUBLISH_H_
+#define __PUA_JSON_PUBLISH_H_
+
+int pua_json_publish(struct sip_msg* msg, char *json);
+
+#endif