diff --git a/src/modules/presence/bind_presence.h b/src/modules/presence/bind_presence.h index 31ffdc420ba..5500c09e477 100644 --- a/src/modules/presence/bind_presence.h +++ b/src/modules/presence/bind_presence.h @@ -43,7 +43,7 @@ typedef int (*pres_handle_publish_t)(struct sip_msg* msg, char *str1, char* str2 typedef int (*pres_handle_subscribe0_t)(struct sip_msg* msg); typedef int (*pres_handle_subscribe_t)(struct sip_msg* msg, str watcher_user, str watcher_domain); typedef int (*pres_update_presentity_t)(str *event, str *realm, str *user, str *etag, - str *sender, str *body, int expires, int new_t); + str *sender, str *body, int expires, int new_t, int replace); typedef int (*pres_refresh_watchers_t)(str *pres, str *event, int type); typedef struct presence_api { diff --git a/src/modules/presence/presence_dmq.c b/src/modules/presence/presence_dmq.c index 05f95e85ed1..4cba168a559 100644 --- a/src/modules/presence/presence_dmq.c +++ b/src/modules/presence/presence_dmq.c @@ -302,7 +302,7 @@ int pres_dmq_handle_msg( switch(action) { case PRES_DMQ_UPDATE_PRESENTITY: if(update_presentity(NULL, presentity, &p_body, t_new, &sent_reply, - sphere, &cur_etag, &ruid) + sphere, &cur_etag, &ruid, 0) < 0) { goto error; } diff --git a/src/modules/presence/presentity.c b/src/modules/presence/presentity.c index 231f9a8bd57..1c7c4240b97 100644 --- a/src/modules/presence/presentity.c +++ b/src/modules/presence/presentity.c @@ -281,7 +281,7 @@ int check_if_dialog(str body, int *is_dialog, char **dialog_id) doc = xmlParseMemory(body.s, body.len); if(doc== NULL) { - LM_ERR("failed to parse xml document\n"); + LM_INFO("failed to parse xml document\n"); return -1; } @@ -556,7 +556,7 @@ int is_dialog_terminated(presentity_t* presentity) } int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, - int new_t, int* sent_reply, char* sphere, str* etag_override, str* ruid) + int new_t, int* sent_reply, char* sphere, str* etag_override, str* ruid, int replace) { db_key_t query_cols[14], rquery_cols[2], update_keys[9], result_cols[7]; db_op_t query_ops[14], rquery_ops[2]; @@ -658,6 +658,9 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, } LM_DBG("new htable record added\n"); + if (presentity->expires == -1) { + replace = 1; + } /* insert new record into database */ query_cols[n_query_cols] = &str_sender_col; @@ -697,7 +700,7 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].val.str_val = p_ruid; n_query_cols++; - if (presentity->expires != -1) + if (!replace) { /* A real PUBLISH */ query_cols[n_query_cols] = &str_expires_col; @@ -748,6 +751,10 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body, query_vals[n_query_cols].type = DB1_INT; query_vals[n_query_cols].nul = 0; query_vals[n_query_cols].val.int_val = -1; + if(presentity->expires != -1) { + query_vals[n_query_cols].val.int_val = + presentity->expires + (int)time(NULL); + } n_query_cols++; if (pa_dbf.use_table(pa_db, &presentity_table) < 0) @@ -1918,7 +1925,7 @@ int delete_offline_presentities(str *pres_uri, pres_ev_t *event) // used for API updates to the presentity table int _api_update_presentity(str *event, str *realm, str *user, str *etag, - str *sender, str *body, int expires, int new_t) + str *sender, str *body, int expires, int new_t, int replace) { int ret; presentity_t *pres = NULL; @@ -1936,7 +1943,7 @@ int _api_update_presentity(str *event, str *realm, str *user, str *etag, if(sphere_enable) { sphere = extract_sphere(*body); } - ret = update_presentity(NULL, pres, body, new_t, NULL, sphere, NULL, NULL); + ret = update_presentity(NULL, pres, body, new_t, NULL, sphere, NULL, NULL, replace); if(pres) pkg_free(pres); diff --git a/src/modules/presence/presentity.h b/src/modules/presence/presentity.h index c225580ed35..8fe75cf642c 100644 --- a/src/modules/presence/presentity.h +++ b/src/modules/presence/presentity.h @@ -55,11 +55,11 @@ presentity_t* new_presentity( str* domain,str* user,int expires, /* update presentity in database */ int update_presentity(struct sip_msg* msg,presentity_t* p,str* body,int t_new, - int* sent_reply, char* sphere, str* etag_override, str* ruid); + int* sent_reply, char* sphere, str* etag_override, str* ruid, int replace); /* update presentity in database using API */ int _api_update_presentity(str *event, str *realm, str *user, str *etag, - str *sender, str *body, int expires, int reset); + str *sender, str *body, int expires, int new_t, int replace); /* free memory */ void free_presentity(presentity_t *p); diff --git a/src/modules/presence/publish.c b/src/modules/presence/publish.c index bf5a3bcd56d..8f27843e680 100644 --- a/src/modules/presence/publish.c +++ b/src/modules/presence/publish.c @@ -494,7 +494,7 @@ int ki_handle_publish_uri(struct sip_msg* msg, str* sender_uri) } /* querry the database and update or insert */ - if(update_presentity(msg, presentity, &body, etag_gen, &sent_reply, sphere, NULL, NULL) <0) + if(update_presentity(msg, presentity, &body, etag_gen, &sent_reply, sphere, NULL, NULL, 0) <0) { LM_ERR("when updating presentity\n"); goto error; @@ -635,7 +635,7 @@ int update_hard_presentity(str *pres_uri, pres_ev_t *event, str *file_uri, str * goto done; } - if (update_presentity(NULL, pres, pidf_doc, new_t, NULL, sphere, NULL, NULL) < 0) + if (update_presentity(NULL, pres, pidf_doc, new_t, NULL, sphere, NULL, NULL, 0) < 0) { LM_ERR("updating presentity\n"); goto done; diff --git a/src/modules/pua_json/Makefile b/src/modules/pua_json/Makefile new file mode 100644 index 00000000000..cfbd69d6b5d --- /dev/null +++ b/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 diff --git a/src/modules/pua_json/README b/src/modules/pua_json/README new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/modules/pua_json/defs.h b/src/modules/pua_json/defs.h new file mode 100644 index 00000000000..47db1434b8c --- /dev/null +++ b/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 + * + */ + +#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 "\ + \ +\ +\ +%s\ +\ +\ +%s\ +\ +%s\ +%s\ +\ +" + +#define DIALOGINFO_EMPTY_BODY "\ + \ +\ +terminated\ +\ +" + +#define LOCAL_TAG "local-tag=\"%.*s\"" +#define REMOTE_TAG "remote-tag=\"%.*s\"" + +#define DIALOGINFO_BODY "\ +\ +\ +%.*s\ +\ +%.*s\ +\ +\ +\ +%.*s\ +\ +\ +\ +" + +#define DIALOGINFO_BODY_2 "\ +\ +\ +%.*s\ +\ +%.*s\ +\ +\ +%.*s\ +\ +\ +" + +#endif /* _PUA_JSON_DEFS_H_ */ diff --git a/src/modules/pua_json/doc/Makefile b/src/modules/pua_json/doc/Makefile new file mode 100644 index 00000000000..253a1aa1f47 --- /dev/null +++ b/src/modules/pua_json/doc/Makefile @@ -0,0 +1,4 @@ +docs = json_pua.xml + +docbook_dir = ../../../../doc/docbook +include $(docbook_dir)/Makefile.module diff --git a/src/modules/pua_json/doc/pua_json.xml b/src/modules/pua_json/doc/pua_json.xml new file mode 100644 index 00000000000..00920831fdf --- /dev/null +++ b/src/modules/pua_json/doc/pua_json.xml @@ -0,0 +1,37 @@ + + + +%docentities; + +]> + + + + PUA_JSON Module + &kamailioname; + + + Emmanuel Schmidbauer + eschmidbauer@gmail.com + + + Emmanuel + Schmidbauer + eschmidbauer@gmail.com + + + + 2018 + VoIPxSWITCH + + + + + + + + + diff --git a/src/modules/pua_json/doc/pua_json_admin.xml b/src/modules/pua_json/doc/pua_json_admin.xml new file mode 100644 index 00000000000..b6f58d06183 --- /dev/null +++ b/src/modules/pua_json/doc/pua_json_admin.xml @@ -0,0 +1,105 @@ + + + +%docentities; + +]> + + + + &adminguide; + + +
+ Overview + The PUA_JSON module adds support to publish updates to the presence module through the pua_json_publish() function. + + + From a high-level perspective, the module may be used for: + + + + Providing a real-time presence updates. + + + + + +
+
+ How it works + + The module parses json data objects and inserts them into the presentity table for real-time presence updates. + +
+ +
+ Dependencies +
+ &kamailio; Modules + + The following modules must be loaded before this module: + + + + none. + + + + +
+
+ External Libraries or Applications + + The following libraries or applications must be installed + + + + libjson. + + + + +
+
+ +
+ Functions +
+ + <function moreinfo="none">pua_json_publish(json_payload)</function> + + + The function build presentity state from json_payload and updates presentity table. + + + Usage: presence related. + + + This function can be used from ANY ROUTE. + + + + <function>pua_json_publish</function> usage + +... +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); + } +} +... + + +
+ +
+ + +
+ diff --git a/src/modules/pua_json/pua_json_mod.c b/src/modules/pua_json/pua_json_mod.c new file mode 100644 index 00000000000..be68da335bd --- /dev/null +++ b/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 +#include + +#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; +} diff --git a/src/modules/pua_json/pua_json_mod.h b/src/modules/pua_json/pua_json_mod.h new file mode 100644 index 00000000000..c558cdacdce --- /dev/null +++ b/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 diff --git a/src/modules/pua_json/pua_json_publish.c b/src/modules/pua_json/pua_json_publish.c new file mode 100644 index 00000000000..e601337476f --- /dev/null +++ b/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 + * + */ + +#include +#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(""); +str str_presence_act_otp = str_init(""); +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; +} diff --git a/src/modules/pua_json/pua_json_publish.h b/src/modules/pua_json/pua_json_publish.h new file mode 100644 index 00000000000..23792470895 --- /dev/null +++ b/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 + * + */ + +#ifndef __PUA_JSON_PUBLISH_H_ +#define __PUA_JSON_PUBLISH_H_ + +int pua_json_publish(struct sip_msg* msg, char *json); + +#endif