Skip to content

Commit

Permalink
Merge pull request #667 from ionel-cerghit/kill_dialogs
Browse files Browse the repository at this point in the history
modules/dialog: add mi command to terminate all dialogs from a profile
  • Loading branch information
bogdan-iancu committed Dec 3, 2015
2 parents aa91970 + 3e1dc7d commit 671fa5c
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 10 deletions.
36 changes: 28 additions & 8 deletions modules/dialog/README
Expand Up @@ -125,10 +125,11 @@ Vladut-Stefan Paiu
1.9.4. profile_get_size
1.9.5. profile_list_dlgs
1.9.6. profile_get_values
1.9.7. dlg_db_sync
1.9.8. dlg_restore_db
1.9.9. list_all_profiles
1.9.10. profile_bin_status
1.9.7. profile_end_dlgs
1.9.8. dlg_db_sync
1.9.9. dlg_restore_db
1.9.10. list_all_profiles
1.9.11. profile_bin_status

1.10. Exported pseudo-variables

Expand Down Expand Up @@ -1629,7 +1630,26 @@ $var(account) = $dlg_val(account_type);
inbound_calls
_empty_line_

1.9.7. dlg_db_sync
1.9.7. profile_end_dlgs

Terminate all ongoing dialogs from a specified profile, on a
single dialog it performs the same operations as the command
dlg_end_dlg

Name: profile_end_dlgs

Parameters:
* profile - name of the profile that will have its dialogs
termianted
* value - (optional) if the profile supports values terminate
only the dialogs with the specified value

MI FIFO Command Format:
:profile_end_dlgs:_reply_fifo_file_
inbound_calls
_empty_line_

1.9.8. dlg_db_sync

Will synchronize the information about the dialogs from the
database with the OpenSIPS internal memory. To be used mainly
Expand All @@ -1644,7 +1664,7 @@ $var(account) = $dlg_val(account_type);
:dlg_db_sync:_reply_fifo_file_
_empty_line_

1.9.8. dlg_restore_db
1.9.9. dlg_restore_db

Restores the dialog table after a potential desynchronization
event. The table is truncated, then populated with CONFIRMED
Expand All @@ -1658,7 +1678,7 @@ $var(account) = $dlg_val(account_type);
:dlg_restore_db:_reply_fifo_file_
_empty_line_

1.9.9. list_all_profiles
1.9.10. list_all_profiles

Lists all the dialog profiles, along with 1 or 0 if the given
profile has/does not have an associated value.
Expand All @@ -1671,7 +1691,7 @@ $var(account) = $dlg_val(account_type);
:list_all_profiles:_reply_fifo_file_
_empty_line_

1.9.10. profile_bin_status
1.9.11. profile_bin_status

Dumps each destination used for profiles replication, as well
as the timestamp of the last message received from them.
Expand Down
1 change: 1 addition & 0 deletions modules/dialog/dialog.c
Expand Up @@ -310,6 +310,7 @@ static mi_export_t mi_cmds[] = {
{ "profile_list_dlgs", 0, mi_profile_list, 0, 0, 0},
{ "profile_get_values", 0, mi_get_profile_values, 0, 0, 0},
{ "list_all_profiles", 0, mi_list_all_profiles, 0, 0, 0},
{ "profile_end_dlgs", 0, mi_profile_terminate, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0}
};

Expand Down
96 changes: 96 additions & 0 deletions modules/dialog/dlg_profile.c
Expand Up @@ -35,6 +35,7 @@
#include "dlg_hash.h"
#include "dlg_profile.h"
#include "dlg_repl_profile.h"
#include "dlg_req_within.h"

#define PROFILE_HASH_SIZE 16

Expand Down Expand Up @@ -1280,3 +1281,98 @@ struct mi_root * mi_list_all_profiles(struct mi_root *cmd_tree, void *param )

return rpl_tree;
}

struct mi_root * mi_profile_terminate(struct mi_root *cmd_tree, void *param ) {
struct mi_node* node;
struct dlg_profile_table *profile;
str *profile_name;
str *value;
unsigned int i;
struct dlg_entry *d_entry;
struct dlg_cell *cur_dlg;
struct dlg_profile_link *cur_link;
struct dialog_list *deleted = NULL, *delete_entry ;

node = cmd_tree->node.kids;
if (node==NULL || !node->value.s || !node->value.len)
return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));
profile_name = &node->value;

if (node->next) {
node = node->next;
if (!node->value.s || !node->value.len)
return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
if (node->next)
return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));
value = &node->value;
} else {
value = NULL;
}

profile = search_dlg_profile( profile_name );

if (profile==NULL)
return init_mi_tree( 404, MI_SSTR("Profile not found"));

for (i = 0; i < d_table->size; i++) {
d_entry = &(d_table->entries[i]);
lock_set_get(d_table->locks,d_entry->lock_idx);

cur_dlg = d_entry->first;
while( cur_dlg ) {

cur_link = cur_dlg ->profile_links;

while(cur_link) {
if( cur_link->profile == profile &&
( value == NULL ||
( value->len == cur_link->value.len
&& !strncmp(value->s,cur_link->value.s, value->len))
)) {
delete_entry = pkg_malloc(sizeof(struct dialog_list));
if (!delete_entry) {
LM_CRIT("no more pkg memory\n");
lock_set_release(d_table->locks,d_entry->lock_idx);
return init_mi_tree( 400, MI_SSTR(MI_INTERNAL_ERR));
}

delete_entry->dlg = cur_dlg;
delete_entry->next = deleted;
deleted = delete_entry;

ref_dlg_unsafe(cur_dlg, 1);

break;
}
cur_link = cur_link->next;
}
cur_dlg = cur_dlg->next;
}

lock_set_release(d_table->locks,d_entry->lock_idx);

delete_entry = deleted;
while(delete_entry){
init_dlg_term_reason(delete_entry->dlg,"MI Termination",sizeof("MI Termination")-1);

if ( dlg_end_dlg( delete_entry->dlg, NULL) ) {
while(delete_entry){
deleted = delete_entry;
delete_entry = delete_entry->next;
pkg_free(deleted);
}
LM_CRIT("eror while terminating dlg\n");
return init_mi_tree( 400, MI_SSTR("Dialog internal error"));
}

unref_dlg(delete_entry->dlg, 1);
deleted = delete_entry;
delete_entry = delete_entry->next;
pkg_free(deleted);
}

deleted = NULL;
}

return init_mi_tree(400, MI_SSTR(MI_OK));
}
7 changes: 7 additions & 0 deletions modules/dialog/dlg_profile.h
Expand Up @@ -83,6 +83,11 @@ struct dlg_profile_table {
struct dlg_profile_table *next;
};

struct dialog_list{
struct dlg_cell *dlg;
struct dialog_list *next;
};

typedef int (*set_dlg_profile_f)(struct dlg_cell *dlg, str *value,
struct dlg_profile_table *profile, char is_replicated);

Expand Down Expand Up @@ -131,6 +136,8 @@ struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param );

struct mi_root * mi_list_all_profiles(struct mi_root *cmd_tree, void *param );

struct mi_root * mi_profile_terminate(struct mi_root *cmd_tree, void *param );

void get_value_names(struct dlg_profile_table *profile, struct dlg_profile_value_name *);

/* cachedb interface */
Expand Down
31 changes: 29 additions & 2 deletions modules/dialog/doc/dialog_admin.xml
Expand Up @@ -2154,7 +2154,7 @@ $var(account) = $dlg_val(account_type);
</programlisting>
</section>

<section>
<section id='dlg_end_dlg' xreflabel="dlg_end_dlg">
<title><varname>dlg_end_dlg</varname></title>
<para>
Terminates an ongoing dialog.
Expand Down Expand Up @@ -2293,7 +2293,34 @@ $var(account) = $dlg_val(account_type);
_empty_line_
</programlisting>
</section>

<section>
<title><varname>profile_end_dlgs</varname></title>
<para>
Terminate all ongoing dialogs from a specified profile, on a single dialog it
performs the same operations as the command <emphasis role='bold'><xref linkend="dlg_end_dlg"/></emphasis>
</para>
<para>
Name: <emphasis>profile_end_dlgs</emphasis>
</para>
<para>Parameters:</para>
<itemizedlist>
<listitem><para>
<emphasis>profile</emphasis> - name of the profile that will have its dialogs termianted
</para></listitem>
<listitem><para>
<emphasis>value</emphasis> - (optional) if the profile supports values terminate only the dialogs
with the specified value
</para></listitem>
</itemizedlist>
<para>
MI FIFO Command Format:
</para>
<programlisting format="linespecific">
:profile_end_dlgs:_reply_fifo_file_
inbound_calls
_empty_line_
</programlisting>
</section>
<section>
<title><varname>dlg_db_sync</varname></title>
<para>
Expand Down

0 comments on commit 671fa5c

Please sign in to comment.