Skip to content

Commit

Permalink
dialog: rpc kill_active_dlg replaced with dlg.set_state
Browse files Browse the repository at this point in the history
- enable the option to set different state values, although right now
targets the turning confirmed in terminated
  • Loading branch information
miconda committed Oct 30, 2019
1 parent 22028f7 commit f25bef9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 30 deletions.
62 changes: 38 additions & 24 deletions src/modules/dialog/dialog.c
Expand Up @@ -2368,8 +2368,10 @@ static const char *rpc_end_dlg_entry_id_doc[2] = {
static const char *rpc_dlg_terminate_dlg_doc[2] = {
"End a given dialog based on callid", 0
};
static const char *rpc_dlg_kill_active_dlg_doc[2] = {
"Kill a given active dialog based on callid and tags", 0
static const char *rpc_dlg_set_state_doc[3] = {
"Set state for a dialog based on callid and tags",
"It is targeting the need to update from state 4 (confirmed) to 5 (terminated)",
0
};
static const char *rpc_profile_get_size_doc[2] = {
"Returns the number of dialogs belonging to a profile", 0
Expand Down Expand Up @@ -2438,53 +2440,65 @@ static void rpc_dlg_terminate_dlg(rpc_t *rpc,void *c){
}
}

static void rpc_dlg_kill_active_dlg(rpc_t *rpc,void *c){
static void rpc_dlg_set_state(rpc_t *rpc,void *c){
str callid = {NULL,0};
str ftag = {NULL,0};
str ttag = {NULL,0};
int sval = DLG_STATE_DELETED;
int ostate = 0;

dlg_cell_t * dlg = NULL;
unsigned int dir;
int unref=1;
dir = 0;

if(rpc->scan(c, ".S.S.S", &callid,&ftag,&ttag)<3) {
LM_ERR("Unable to read the parameters dlg_terminate_dlg \n" );
rpc->fault(c, 400, "Need a Callid ,from tag ,to tag");
if(rpc->scan(c, ".S.S.Sd", &callid, &ftag, &ttag, &sval)<3) {
LM_ERR("unable to read the parameters\n" );
rpc->fault(c, 400, "Need the callid, from tag,to tag and state");
return;
}
if(sval < DLG_STATE_UNCONFIRMED || sval > DLG_STATE_DELETED) {
LM_ERR("invalid new state value: %d\n", sval);
rpc->fault(c, 500, "Invalid state value");
return;
}

dlg=get_dlg(&callid, &ftag, &ttag, &dir);

if(dlg==NULL) {
LM_ERR("Couldnt find callid in dialog '%.*s' \n",callid.len, callid.s);
rpc->fault(c, 500, "Couldnt find callid in dialog");
LM_ERR("dialog not found - callid '%.*s' \n", callid.len, callid.s);
rpc->fault(c, 500, "Dialog not found");
return;
}

LM_DBG("Dialog is found with callid '%.*s' for kill_active_dlg rpc \n",
callid.len, callid.s);
LM_DBG("dialog found - callid '%.*s'\n", callid.len, callid.s);

if(dlg->state != 4) {
LM_ERR("Not handling dialog with callid '%.*s': should be in active state to run this command \n",
callid.len, callid.s);
rpc->fault(c, 500, "Dialog not in active state");
return;
if(dlg->state != DLG_STATE_CONFIRMED || sval!=DLG_STATE_DELETED) {
LM_WARN("updating states for not confirmed dialogs not properly supported yet,"
" use at own risk: '%.*s'\n", callid.len, callid.s);
}

/* Forcing next state for this dialog */
dlg->state = 5;
/* Updating timestamps, flags, dialog stats */
dlg->init_ts = (unsigned int)(time(0));
dlg->end_ts = (unsigned int)(time(0));
/* setting new state for this dialog */
ostate = dlg->state;
dlg->state = sval;

/* updates for terminated dialogs */
if(ostate==DLG_STATE_CONFIRMED && sval==DLG_STATE_DELETED) {
/* updating timestamps, flags, dialog stats */
dlg->init_ts = (unsigned int)(time(0));
dlg->end_ts = (unsigned int)(time(0));
}
dlg->dflags |= DLG_FLAG_NEW;

dlg_unref(dlg, unref);
if_update_stat(dlg_enable_stats, active_dlgs, -1);

if(ostate==DLG_STATE_CONFIRMED && sval==DLG_STATE_DELETED) {
if_update_stat(dlg_enable_stats, active_dlgs, -1);
}

/* dlg_clean_run called by timer execution will handle timers deletion and all that stuff */
LM_NOTICE("Dialog '%.*s' forced to deleted state: will be wiped out from memory in a few minutes \n",
callid.len, callid.s);
LM_NOTICE("dialog callid '%.*s' - state change forced - old: %d - new: %d\n",
callid.len, callid.s, ostate, sval);

rpc->add(c, "s", "Done");

Expand Down Expand Up @@ -2835,7 +2849,7 @@ static rpc_export_t rpc_methods[] = {
{"dlg.profile_list", rpc_profile_print_dlgs, rpc_profile_print_dlgs_doc, RET_ARRAY},
{"dlg.bridge_dlg", rpc_dlg_bridge, rpc_dlg_bridge_doc, 0},
{"dlg.terminate_dlg", rpc_dlg_terminate_dlg, rpc_dlg_terminate_dlg_doc, 0},
{"dlg.kill_active_dlg", rpc_dlg_kill_active_dlg, rpc_dlg_kill_active_dlg_doc, 0},
{"dlg.set_state", rpc_dlg_set_state, rpc_dlg_set_state_doc, 0},
{"dlg.stats_active", rpc_dlg_stats_active, rpc_dlg_stats_active_doc, 0},
{"dlg.is_alive", rpc_dlg_is_alive, rpc_dlg_is_alive_doc, 0},
{0, 0, 0, 0}
Expand Down
17 changes: 11 additions & 6 deletions src/modules/dialog/doc/dialog_admin.xml
Expand Up @@ -2600,9 +2600,9 @@ if(has_totag()) {
</programlisting>
</section>
<section>
<title>dlg.kill_active_dlg</title>
<title>dlg.set_state</title>
<para>
Kills a given active dialog matching the dialog on Call-ID, From-Tag and To-Tag.
Set state for the dialog matching the dialog on Call-ID, From-Tag and To-Tag.
</para>
<para>Name: <emphasis>dlg.kill_active_dlg</emphasis></para>
<para>Parameters:</para>
Expand All @@ -2616,19 +2616,24 @@ if(has_totag()) {
<listitem><para>
<emphasis>to_tag</emphasis> - To-tag of active dialog to kill
</para></listitem>
<listitem><para>
<emphasis>state</emphasis> - The value for new state
</para></listitem>
</itemizedlist>
<para>
This command only handles active dialogs (state 4), error is returned otherwise.
Please be careful with it, it callously wipes out the given dialog: dialog ending
functions will not be called, such as accounting end-of-call events, dialog-end
At this moment, the command targets the need to change from active dialogs
(state 4) to terminated state (5), although it allows setting other state
value. Be careful using with it, it can cause side effects and the
terminated dialog is wiped out silently. Dialog ending functions are not
executed, such as accounting end-of-call events, dialog-end
events, module-generated BYE requests, etc. After executing the command, dialog
remains in memory until execution of the recurring function in charge of removing
old dialogs (a "dialog in delete state is too old" will then be logged).
</para>
<para>RPC Command Format:</para>
<programlisting format="linespecific">
...
&kamcmd; dlg.kill_active_dlg callid12345 fromtag123 totag123
&kamcmd; dlg.set_state callid12345 fromtag123 totag123 5
...
</programlisting>
</section>
Expand Down

0 comments on commit f25bef9

Please sign in to comment.