Module: sip-router
Branch: master
Commit: 7ba6a2af28651ba363059cb444832b6cfce9a9db
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7ba6a2a…
Author: Richard Good <richard.good(a)smilecoms.com>
Committer: Richard Good <richard.good(a)smilecoms.com>
Date: Wed Mar 5 13:31:57 2014 +0200
modules/ims_usrloc_scscf: add dialog data to contact and tear down dialog when contact is
removed
Added info to contact structure to store active dialogs for contact
When contact is removed terminate all active dialogs
Added new API functions: api->add_dialog_data_to_contact and
api->remove_dialog_data_from_contact
---
modules/ims_usrloc_scscf/impurecord.c | 12 +++++
modules/ims_usrloc_scscf/ucontact.c | 73 +++++++++++++++++++++++++++++++++
modules/ims_usrloc_scscf/ucontact.h | 4 ++
modules/ims_usrloc_scscf/ul_mod.c | 18 ++++++++-
modules/ims_usrloc_scscf/usrloc.c | 2 +
modules/ims_usrloc_scscf/usrloc.h | 19 +++++++++
6 files changed, 127 insertions(+), 1 deletions(-)
diff --git a/modules/ims_usrloc_scscf/impurecord.c
b/modules/ims_usrloc_scscf/impurecord.c
index bdabe20..184c4a3 100644
--- a/modules/ims_usrloc_scscf/impurecord.c
+++ b/modules/ims_usrloc_scscf/impurecord.c
@@ -58,6 +58,8 @@
#include "subscribe.h"
#include "usrloc_db.h"
#include "../../lib/ims/useful_defs.h"
+#include "../../modules/dialog_ng/dlg_load.h"
+#include "../../modules/dialog_ng/dlg_hash.h"
/*! contact matching mode */
int matching_mode = CONTACT_ONLY;
@@ -72,6 +74,8 @@ extern int db_mode;
extern int sub_dialog_hash_size;
extern shtable_t sub_dialog_table;
+extern struct dlg_binds dlgb;
+
/*!
* \brief Create and initialize new record structure
* \param _dom domain name
@@ -322,6 +326,14 @@ void mem_remove_ucontact(impurecord_t* _r, ucontact_t* _c) {
* \param _c deleted contact
*/
void mem_delete_ucontact(impurecord_t* _r, ucontact_t* _c) {
+
+ struct contact_dialog_data *dialog_data;
+ //tear down dialogs in dialog data list
+ for (dialog_data = _c->first_dialog_data; dialog_data;) {
+ dlgb.lookup_terminate_dlg(dialog_data->h_entry, dialog_data->h_id, NULL );
+ dialog_data = dialog_data->next;
+ }
+
mem_remove_ucontact(_r, _c);
if_update_stat(_r->slot, _r->slot->d->contacts, -1);
free_ucontact(_c);
diff --git a/modules/ims_usrloc_scscf/ucontact.c b/modules/ims_usrloc_scscf/ucontact.c
index 42e085b..6699a8a 100644
--- a/modules/ims_usrloc_scscf/ucontact.c
+++ b/modules/ims_usrloc_scscf/ucontact.c
@@ -133,6 +133,7 @@ error:
*/
void free_ucontact(ucontact_t* _c) {
struct ul_callback *cbp, *cbp_tmp;
+ struct contact_dialog_data *dialog_data, *tmp_dialog_data;
if (!_c) return;
if (_c->path.s) shm_free(_c->path.s);
@@ -141,6 +142,13 @@ void free_ucontact(ucontact_t* _c) {
if (_c->callid.s) shm_free(_c->callid.s);
if (_c->c.s) shm_free(_c->c.s);
+ //free dialog data
+ for (dialog_data = _c->first_dialog_data; dialog_data;) {
+ tmp_dialog_data = dialog_data;
+ dialog_data = dialog_data->next;
+ shm_free(tmp_dialog_data);
+ }
+
//free callback list
for (cbp = _c->cbs->first; cbp;) {
cbp_tmp = cbp;
@@ -355,3 +363,68 @@ int update_ucontact(struct impurecord* _r, ucontact_t* _c,
ucontact_info_t* _ci)
return 0;
}
+
+
+/*!
+ * \brief Add dialog data to contact
+ * used when this contact is part of a confirmed dialog so we can tear down the dialog if
the contact is removed
+ */
+int add_dialog_data_to_contact(ucontact_t* _c, unsigned int h_entry, unsigned int h_id)
{
+
+ struct contact_dialog_data *dialog_data = (struct
contact_dialog_data*)shm_malloc(sizeof( struct contact_dialog_data));
+
+ LM_DBG("Adding dialog data to contact <%.*s> with h_entry <%d> and
h_id <%d>", _c->c.len, _c->c.s, h_entry, h_id);
+
+ memset(dialog_data, 0, sizeof( struct contact_dialog_data));
+
+ dialog_data->h_entry = h_entry;
+ dialog_data->h_id = h_id;
+ dialog_data->next = 0;
+ dialog_data->prev = 0;
+
+ if(_c->first_dialog_data==0){
+ //first entry in the list
+ _c->first_dialog_data = dialog_data;
+ _c->last_dialog_data = dialog_data;
+ }else {
+ //not first entry in list
+ _c->last_dialog_data->next = dialog_data;
+ dialog_data->prev = _c->last_dialog_data;
+ _c->last_dialog_data = dialog_data;
+ }
+
+ return 0;
+
+}
+
+/*!
+ * \brief Add dialog data to contact
+ * used when this contact is part of a confirmed dialog so we can tear down the dialog if
the contact is removed
+ */
+int remove_dialog_data_from_contact(ucontact_t* _c, unsigned int h_entry, unsigned int
h_id) {
+ struct contact_dialog_data *dialog_data, *tmp_dialog_data;
+ LM_DBG("Removing dialog data from contact <%.*s> with h_entry <%d>
and h_id <%d>", _c->c.len, _c->c.s, h_entry, h_id);
+
+ for (dialog_data = _c->first_dialog_data; dialog_data;) {
+ tmp_dialog_data = dialog_data;
+ dialog_data = dialog_data->next;
+ if(tmp_dialog_data->h_entry == h_entry && tmp_dialog_data->h_id == h_id){
+ LM_DBG("Found matching dialog data so will remove it");
+ if(tmp_dialog_data->prev) {
+ tmp_dialog_data->prev->next = tmp_dialog_data->next;
+ } else {
+ _c->first_dialog_data = tmp_dialog_data->next;
+ }
+ if(tmp_dialog_data->next){
+ tmp_dialog_data->next->prev = tmp_dialog_data->prev;
+ }else{
+ _c->last_dialog_data = tmp_dialog_data->prev;
+ }
+ shm_free(tmp_dialog_data);
+ return 0;
+ }
+
+ }
+ LM_DBG("Did not find dialog data to remove from contact");
+ return 0;
+}
diff --git a/modules/ims_usrloc_scscf/ucontact.h b/modules/ims_usrloc_scscf/ucontact.h
index b799a80..52369c3 100644
--- a/modules/ims_usrloc_scscf/ucontact.h
+++ b/modules/ims_usrloc_scscf/ucontact.h
@@ -107,4 +107,8 @@ int mem_update_ucontact(ucontact_t* _c, ucontact_info_t *_ci);
*/
int update_ucontact(struct impurecord* _r, ucontact_t* _c, ucontact_info_t* _ci);
+int remove_dialog_data_from_contact(ucontact_t* _c, unsigned int h_entry, unsigned int
h_id);
+
+int add_dialog_data_to_contact(ucontact_t* _c, unsigned int h_entry, unsigned int h_id);
+
#endif
diff --git a/modules/ims_usrloc_scscf/ul_mod.c b/modules/ims_usrloc_scscf/ul_mod.c
index d1c95c1..e06d72a 100644
--- a/modules/ims_usrloc_scscf/ul_mod.c
+++ b/modules/ims_usrloc_scscf/ul_mod.c
@@ -64,6 +64,9 @@
#include "../presence/bind_presence.h"
#include "../presence/hash.h"
+#include "../../modules/dialog_ng/dlg_load.h"
+#include "../../modules/dialog_ng/dlg_hash.h"
+
MODULE_VERSION
#define DEFAULT_DBG_FILE "/var/log/usrloc_debug"
@@ -105,6 +108,8 @@ str db_url = str_init(DEFAULT_DB_URL); /*!< Database URL
*/
unsigned int nat_bflag = (unsigned int)-1;
unsigned int init_flag = 0;
+struct dlg_binds dlgb;
+
int sub_dialog_hash_size = 9;
shtable_t sub_dialog_table;
@@ -184,6 +189,7 @@ struct module_exports exports = {
*/
static int mod_init(void) {
+ load_dlg_f load_dlg;
if (usrloc_debug){
LM_INFO("Logging usrloc records to %.*s\n", usrloc_debug_file.len,
usrloc_debug_file.s);
debug_file = fopen(usrloc_debug_file.s, "a");
@@ -302,7 +308,17 @@ static int mod_init(void) {
}
}
-
+ if (!(load_dlg = (load_dlg_f) find_export("load_dlg", 0, 0))) { /* bind to
dialog module */
+ LM_ERR("can not import load_dlg. This module requires Kamailio dialog
module.\n");
+ }
+ if (load_dlg(&dlgb) == -1) {
+ return -1;
+ }
+ if (load_dlg_api(&dlgb) != 0) { /* load the dialog API */
+ LM_ERR("can't load Dialog API\n");
+ return -1;
+ }
+
/* Register cache timer */
register_timer(timer, 0, timer_interval);
diff --git a/modules/ims_usrloc_scscf/usrloc.c b/modules/ims_usrloc_scscf/usrloc.c
index 8f2f7e9..14cfcba 100644
--- a/modules/ims_usrloc_scscf/usrloc.c
+++ b/modules/ims_usrloc_scscf/usrloc.c
@@ -89,6 +89,8 @@ int bind_usrloc(usrloc_api_t* api) {
api->delete_ucontact = delete_ucontact;
api->get_ucontact = get_ucontact;
api->update_ucontact = update_ucontact;
+ api->add_dialog_data_to_contact = add_dialog_data_to_contact;
+ api->remove_dialog_data_from_contact = remove_dialog_data_from_contact;
api->get_subscriber = get_subscriber;
api->add_subscriber = add_subscriber;
diff --git a/modules/ims_usrloc_scscf/usrloc.h b/modules/ims_usrloc_scscf/usrloc.h
index df07781..1ace70d 100644
--- a/modules/ims_usrloc_scscf/usrloc.h
+++ b/modules/ims_usrloc_scscf/usrloc.h
@@ -271,6 +271,15 @@ typedef struct security {
float q;
} security_t;
+/*! \brief Structure to hold dialog data used when this contact is part of a confirmed
dialog so we can tear down the dialog if the contact is removed */
+typedef struct contact_dialog_data {
+ unsigned int h_entry;
+ unsigned int h_id;
+
+ struct contact_dialog_data* next; /*!< Next contact in the linked list */
+ struct contact_dialog_data* prev; /*!< Previous contact in the linked list */
+} contact_dialog_data_t;
+
/*! \brief Main structure for handling of registered Contact data */
typedef struct ucontact {
str* domain; /*!< Pointer to domain name (NULL terminated) */
@@ -296,6 +305,9 @@ typedef struct ucontact {
security_t *security; /**< Security-Client Information */
struct ulcb_head_list* cbs; /**< individual callbacks per contact */
+
+ struct contact_dialog_data *first_dialog_data;
+ struct contact_dialog_data *last_dialog_data;
struct ucontact* next; /*!< Next contact in the linked list */
struct ucontact* prev; /*!< Previous contact in the linked list */
@@ -392,6 +404,10 @@ typedef int (*delete_ucontact_t)(struct impurecord* _r, struct
ucontact* _c);
typedef int (*get_ucontact_t)(struct impurecord* _r, str* _c, str* _callid, str* _path,
int _cseq, struct ucontact** _co);
+typedef int (*add_dialog_data_to_contact_t)(struct ucontact* _c, unsigned int h_entry,
unsigned int h_id);
+
+typedef int (*remove_dialog_data_from_contact_t)(struct ucontact* _c, unsigned int
h_entry, unsigned int h_id);
+
typedef void (*lock_udomain_t)(struct udomain* _d, str *_aor);
typedef void (*unlock_udomain_t)(struct udomain* _d, str *_aor);
@@ -447,6 +463,9 @@ typedef struct usrloc_api {
get_all_ucontacts_t get_all_ucontacts;
update_ucontact_t update_ucontact;
//update_user_profile_t update_user_profile;
+
+ add_dialog_data_to_contact_t add_dialog_data_to_contact;
+ remove_dialog_data_from_contact_t remove_dialog_data_from_contact;
add_subscriber_t add_subscriber;
update_subscriber_t update_subscriber;