How to restart Asterisk from Dialplan in FreePBX

In our previous post How to add action on call to custom extension in FreePBX we showed how to get. Moreover, in our post on How to restart Asterisk in FreePBX we explored the three different options of restarting Asterisk, e.g. core restart gracefully.

In this post, we’ll add a dialplan extension (i.e. a number that you can dial) that restarts Asterisk. This will not restart FreePBX, but completely restart (and not only reload) Asterisk itself, loading any new configuration options and re-intializing all SIP trunks, for example. In this case we’re using core restart gracefully, i.e. we’ll be waiting for any currently active calls to finish, but not admit new calls.

Add this block to /etc/asterisk/extensions_custom.conf (see How to add action on call to custom extension in FreePBX):

[from-internal-additional-custom]
exten => 999999,1,Answer()
exten => 999999,n,Wait(0.5)
exten => 999999,n,SayAlpha(OK)
exten => 999999,n,System(bash -c "sleep 1 && asterisk -rx 'core restart gracefully'" &)
exten => 999999,n,Hangup()

Reload Asterisk and now you can call 999999 to restart Asterisk

How it works

Basically, we’re reading OK to the user and then running

System(bash -c "sleep 1 && asterisk -rx 'core restart gracefully'" &)

Basically, you could thing we’ll get away with just running

System(asterisk -rx 'core restart gracefully')

However, this will fail (or at least delay the restart for approximately one minute) because the call initiating the restart is still ongoing. Also, we can’t run System() after Hangup() because Hangup() will terminate the dialplan, hence System() will never run. Hence, we run it with a delay ( sleep 1) in the background (& at the end of the command), causing Asterisk to first cleanly hang up on the call and then the command will be run.

Note that the background & at the end is absolutely essential, omitting it will cause Asterisk to just wait for the sleep 1 && asterisk ... command to finish, not Hangup() in between.

Using bash -c to run the command is just a workaround so we can stuff the multiple chained commands of sleep 1 && asterisk ... into a single command which we can run in the background using the trailing &.