Ver Fonte

dialog: adding RPC dlg.kill_active_dlg command

- only handles active dialogs in state 4
- wipes out a given dialog callously
- no subcalls to dialog-ending functions
- dialog is then removed by the recurring cleaning function execution
- as discussed in sr-users in topic "[Dialog] Removing entries from dialog memory"
Julien Klingenmeyer há 5 anos atrás
pai
commit
e0c7e7dd6b

+ 56 - 0
src/modules/dialog/dialog.c

@@ -2368,6 +2368,9 @@ 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_profile_get_size_doc[2] = {
 	"Returns the number of dialogs belonging to a profile", 0
 };
@@ -2435,6 +2438,58 @@ static void rpc_dlg_terminate_dlg(rpc_t *rpc,void *c){
     }
 }
 
+static void rpc_dlg_kill_active_dlg(rpc_t *rpc,void *c){
+	str callid = {NULL,0};
+	str ftag = {NULL,0};
+	str ttag = {NULL,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");
+		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");
+		return;
+	}
+
+	LM_DBG("Dialog is found with callid '%.*s' for kill_active_dlg rpc \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;
+	}
+
+	/* 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));
+	dlg->dflags |= DLG_FLAG_NEW;
+
+	dlg_unref(dlg, unref);
+	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);
+
+	rpc->add(c, "s", "Done");
+
+}
+
 static void rpc_dlg_is_alive(rpc_t *rpc, void *c)
 {
 	str callid = {NULL, 0};
@@ -2780,6 +2835,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.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}

+ 5 - 0
src/modules/dialog/doc/dialog.xml

@@ -58,6 +58,11 @@
 			<surname>Tiwari</surname>
 			<email>[email protected]</email>
 		</editor>
+		<editor>
+			<firstname>Julien</firstname>
+			<surname>Klingenmeyer</surname>
+			<email>[email protected]</email>
+		</editor>
 	</authorgroup>
 	<copyright>
 		<year>2006</year>

+ 33 - 0
src/modules/dialog/doc/dialog_admin.xml

@@ -2596,6 +2596,39 @@ if(has_totag()) {
 		<programlisting  format="linespecific">
 ...
 &kamcmd; dlg.end_dlg 342 56
+...
+		</programlisting>
+		</section>
+		<section>
+			<title>dlg.kill_active_dlg</title>
+			<para>
+			Kills a given active 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>
+		<itemizedlist>
+			<listitem><para>
+				<emphasis>callid</emphasis> - Call-ID of active dialog to kill
+			</para></listitem>
+			<listitem><para>
+				<emphasis>from_tag</emphasis> - From-Tag of active dialog to kill
+			</para></listitem>
+			<listitem><para>
+				<emphasis>to_tag</emphasis> - To-tag of active dialog to kill
+			</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
+		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
 ...
 		</programlisting>
 		</section>