Asterisk h extension called before sending 603 decline

Hello Community,

I am using Asterisk 16.5.0

I am calling an AGI to clean-up my system after the call is hanged up. One of the clean up actions was calling an API. After checking the tcpdump traces, it appears that the API is being called before the 603 Decline is sent by asterisk which is causing my system to fail. Any ideas about that?

Thank you in advance.

Which SIP channel driver is in use? As well, are you saying that the 603 does not get sent until the ‘h’ extension is completed, or it does occur during execution.

Hello jcolp,

Thank you for the quick reply!

I am using the SIP driver by enabling chan_sip.

I can’t tell if it works in parallel or after finishing the AGI call. I need to modify it with a sleep command to check that, but I has never called the API after sending 603, so probably it is waiting for it. I will come back to you after checking it. Thanks.

I think you can pretty safely say that the dialplan logic will not check that the 603 has been acknowledged, so I think the most you could hope for is that the first attempt is queued for transmission before h is run.

For a successful call, the call is set up before the ACK, and a common problem reported here is that the ACK never arrives, and the call is aborted after about 30 seconds.

Thank you for your reply. I think you mins-understood the issue. Everything is working well and fast, except the order of operations. The content of h extension is being executed before sending 603 where documentation says it should do them after hangup.

Hello again @jcolp,

It appears the decline is being sent when the AGI call is done. This means that the SIP 603 message is sent when h extension script exits.

Any recommendation?

This appears to be the relevant code (in main/pbx.c):


	if (!args || !args->no_hangup_chan) {
		ast_softhangup(c, AST_SOFTHANGUP_APPUNLOAD);
		if (!ast_test_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN)
			&& ast_exists_extension(c, ast_channel_context(c), "h", 1,
				S_COR(ast_channel_caller(c)->id.number.valid,
					ast_channel_caller(c)->id.number.str, NULL))) {
			ast_pbx_h_exten_run(c, ast_channel_context(c));
		}
		ast_pbx_hangup_handler_run(c);
	}

	ast_channel_lock(c);
	ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP);
	ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */
	ast_channel_unlock(c);
	pbx_destroy(ast_channel_pbx(c));
	ast_channel_pbx_set(c, NULL);

	if (!args || !args->no_hangup_chan) {
		ast_hangup(c);
	}

and it seems fairly clear that the A side is only hung up after the h extension is run (obviously one side will have hung up before it got here). This code is run on the PBX thread for the call, so will be synchronous with the execution of the dialplan.

However, my point is that, even ast_hangup© were called earlier, it only starts the process of signalling the hangup, so you cannot assume that the A side has actually received and recognized the final status response, which will be sent asynchronously, both because of queuing in the OS and router buffers, and because retransmissions are handled by a state machine controlled by timers, not by the sequential logic of a thread.

Oh thank you @david551. So you believe there wouldn’t be a way to execute the h script after sending 603 without altering the source code?

I think you meant after.

I’m pretty sure an explicit call of the Hangup() application would queue the 603, but there is no way of ensuring that it has reached, and been recognized, by the peer.

Calling Hangup() explicitly leading to similar behavior. Thank you for sharing your info :+1:

Although I can’t find the Hangup application in the latest code, from older code, it does look as though it only does a soft hangup, and doesn’t request the channel technology driver to signal a hangup.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.