Locking and unlocking a phone?

At our international K-12 school we have just moved from a legacy PBX to an Asterisk installation.

One of the features the legacy PBX had was that you could set up a 4-digit code which you could then press on a phone, and it would lock that phone until you pressed the same 4-digit code again.

Is there some way to set this up with Asterisk, that dialling a predefined code would send a phone into some holding context from which it would only be released when that same code is dialled again (from the same phone, obviously)?

Any suggestions would be appreciated!

Wolf Paul

I’m certain you could do this with the correct combination of phone and context. It would have nothing to do with FreePBX.

One example: Aastra phones have a register action url, which they call up when the phone registers. You can have that url check the state of the phone and lock it if it’s supposed to be locked (this would keep people from being able to reboot the phone and dial.)

Then you just set up an context-extension that just goes to hold music or something, then sets a custom value in the asterisk database (or anything else that can track the state.) Dial that extension and you’re gold.

I’d like to implement this in a fashion which is not dependend on a particular phone model but should work with everything.

How about this:

  • Define a Feature Code (say *99) which calls a custom app which prompts for a 4-digit pin code.

  • User enters that pin code and the custom app stores it either in the asterisk db or in a MySQL table, keyed to the extension of the phone.

  • At the beginning of [from-internal] check whether there is a pin code stored for that extension. If so prompt for it, and if corrct delete it from the db and hang up. If not, let dialling proceed.

This would permit users to ANSWER the phone, but not make any calls.

The advantage of this is that it would survive a restart of asterisk, a reboot of the phone, a replacement of the phone, etc. That particular extension would be locked until that pin was deleted from the database.

Is it possible to query and modify a MySQL database from the dialplan, without using an AGI? Because I don’t think the Asterisk DB lets you set up a separate table for this.

Yes it does, you can put in arbitrary stuff in the asterisk database.

From the asterisk cli do:

database show

database xxx yyy zzz

database show

In the second database show command you’ll see a family / key of /xxx/yyy with a value of zzz.

Do database deltree xxx to delete that family.

You can add new keys to existing families, too. So you can just add a new key to the particular extension and call it “outlock” or something, and treat it as a boolean.

That gets me a good stretch further along the way to solving this.

Can you expand on why you want to lock the phones? Is it just to prevent external calls being made on the phone or to stop the phone being used altogether?

If it is the former, you could put a password or pin set on the outbound routes to prevent external calls being made without knowing the password or pin.

Another option may be to use the users & devices functionality and leave the phones without a user when not in use?


O.K., here is the rationale:

We are a K-12 school (Kindergarden through 12th grade), and the main phone this is for (although I would prefer a generalized solution) is the phone on our front desk.

Because our building is used by other groups in the community when school is not in session (evenings, weekends), when the front desk is not occupied, we want to stop people from making (at least) outside calls – preferably all calls.

Requiring a PIN for all outside calls, or requiring user logon is not a solution because our receptionists are mostly non tech-savvy parent volunteers to whom the idea of logging on to a phone is absolutely foreign and the idea of dialling a PIN for all outside calls seems tedious. After all, computers are supposed to make life easier, not more complicated (at least for the ordinary user).

Requiring them to dial a code to lock the phone I can justify because that’s what they did on the legacy PBX as well.


I think the KodaK solution is probably going to be the best for you. In freepbx you change the extension context to a custom one (i.e. custom-checklock) and then if the lock check is successfully goto the from-internal context.

I am going to have a quick look at writing one for you… Are you happy with a hard coded PIN number you can just change in the code if you need to?

I was thinking along the lines of if you try to make a call with the extension locked, you will be prompted for the PIN, which will unlock the phone and carry on with the call. After that, you will be able to make calls until you lock the extension again with a feature code. Does that sound ok?


One side comment. Make sure that no matter what anybody can dial 911 at any time or you will be on the end of a huge law suite if somebody suddenly needs emergency services when it’s locked.


Below is the custom lock code you need to copy into your extensions_custom.conf file. You need to change the context on the extension to be ‘custom-checklock’ so it will check if the extension is locked when trying to dial. The prompt on the phone is currently a simple ‘Password?’ and when you lock an extension you just get ‘Goodbye’. You can change the prompts used to anything you want, including recording your own.

Set the VALIDPIN entry to be the PIN code you want to use and set the 911 emergency bypass (thanks fskrotzki) to whatever the emergency number is in your country.

Finally, set the feature code you want to use for locking the phone to point to ‘custom-setlock,s,1’.

It works by checking a database entry, and if it exists it asks for the PIN (don’t forget to press # after the PIN number). You get three attempts to enter the pin then it hangs up. If you get the PIN right, it deletes the database entry and carries on with the code so next time you dial you just get straight out. Dialling the feature code will add the database entry back in and lock the extension.

That should be it. I have done some testing on an Asterisk V1.4/FreePBX V2.5 system but, as it is free, no warranties expressed or implied etc. etc.


exten => _.,1,NoOp(AMPUSER/${CALLERID(num)}/locked)
exten => _.,n,Gotoif($[${DB_EXISTS(AMPUSER/${CALLERID(num)}/locked)}=0]?carryon)
exten => _.,n,Set(PINCOUNT=0)
exten => _.,n,Set(VALIDPIN=1234)
exten => _.,n(readpin),Read(PIN,vm-password,)
exten => _.,n,Gotoif($[${PIN}=${VALIDPIN}]?carryon)
exten => _.,n,Set(PINCOUNT=$[${PINCOUNT}+1])
exten => _.,n,Playback(vm-incorrect)
exten => _.,n,GotoIf($[${PINCOUNT}>3]?h)
exten => _.,n,Wait(1)
exten => _.,n,Goto(readpin)
exten => _.,n(carryon),NoOp(${DB_DELETE(AMPUSER/${CALLERID(num)}/locked)})
exten => _.,n,Goto(from-internal,${EXTEN},1)
exten => h,1,Hangup
exten => 911,1,Goto(from-internal,${EXTEN},1)

exten => s,1,NoOp(In Set Lock)
exten => s,n,Set(DB(AMPUSER/${CALLERID(num)}/locked)=1)
exten => s,n,Playback(vm-goodbye)
exten => s,n,Hangup

I did some custom prompts (it says “The phone is now locked” when one dials the feature code (*525 for LCK), and it says “The phone is now unlocked. Your call will be placed” when unlocking succeeds).

But otherwise it works fine, including the exceptions for emergency numbers (here in Austria we have three, for ambulance, police, and fire department, as well as the European standard 112.

Thanks again!


No problem, glad to be of help.


what else could you see a use for this as?
just curious


I just wrote this specifically to deal with wnpaul’s issue, but I guess it would be useful for any handset in a public area (i.e. hotel house phones) where you don’t want to allow unlimited outbound calling.

As it is at the moment, when the phone is locked it still allows inbound calls and outbound emergency calls. It could easily be modified, just by amending the extension it matches, to allow any internal calls but not external.

gwhosting, do you have a particular requirement in mind?


hey Graham;
I’m getting a web hosting company up and going and am thinking of getting soft phones and or hard phone for my representatives. This would make integration to the asterisk system, supposedly easier, however i don’t want them calling out long distance. I could care less if they called us and canada, being i have unlimited out calling to the us and canada via sip, but once they go out of those 2 countries rates get, er, um, expensive. So was thinking of a code they would have to be required to enter in order to call those other countries being that they might have to call, or they might email me or im me and ask me to unlock there phone for that particular call. I have one representative that i am not sure if i could trust, but that’s neither here nor is it there. So am looking for some ideas. I would eventually like an email with the call information:
e-mailed to me, but am not going to worry about that as of yet.
anyways hope this explains to you a bit more about what I’m looking for.


You can do what you want using normal features of FreePBX. If you configure your outbound routes so any calls that aren’t the US or Canada require a password or a PIN, then you can prevent your agents from calling other countries.


wow, thanks is this plain in the out bound rutes feature?

Yes, when you define the route there is a password box, and if you have installed the pinsets module a drop down for selecting a pinset.


One of the first other uses I can see is the elevator phone I need to implement. It should allow emergency calls, as well as calls to the school’s building manager and to the elevator company, but putting in a PIN would allow staff (not students and visitors) to make other calls. (Actually, that would probably call more for personal PINs).

But I guess the method of setting a flag by dialling a feature code, and then checking for that flag when processing starts, would allow one to implement all sorts of custom features and conditions for a phone.

One thing that comes to mind is a selective DND feature: allow only calls from the PA, allow only internal calls, allow only external calls, etc.

For Mike’s scenario, you could have a context that allows you to enter an extension number to enable that extension number to make international calls (in other words, instead of setting a flag for $CALLERID(number), set the flag for $EXTEN:x where x is the length of the feature code to strip from the beginning). That context would be set for Mike’s phone, so only he could authorize international calls. Then you could have one feature code which allows exactly one call to be placed, and another one that generally allows int. calling but which gets reset every night, or after two hours, or whatever.

Anyway, lots of useful things come to mind …

thanks for all this information.