Wednesday, November 10, 2010

Asterisk and SIP 911/E911 Support

The Plan:
In our company we have 4 locations, and we have to provide VoIP/SIP E911 support to 3 of them; the 4th is in the Philippines and there is no regional 911 type service there.  I'm sharing what/how I implemented E911 because it may be useful.

The Theory:
First off, for each office we had our ITSP configure a DID for each location with our address and company name.  Then, if somebody from that office calls 911 we must send that DID as the callerid for the call so the 911 responder gets the right address.  To do this, we have different extension ranges for each office so I filtered based on extension.  A 10xx series extension is in San Mateo, 11xx in Makati, 15xx in Redmond, 16xx  in Redmond, and 18xx in Lacey. If you wanted you could probably use another way to decide which location a caller was coming from, maybe look at the SIP Client's IP address, but this method worked for us so we used it.

Additionally, we want to alert some of the people in our office if 911 is ever dialed so we know what is going on.  The receptionist used to get calls saying "we just got a 911 call from you" and had no idea what was going on.   So when anybody dials 911 an email is sent to HR, myself, and the receptionist saying who dialed 911 from what phone, what DID was sent to tell the 911 center where to call, etc.

The final thing we did was added a handy feature that sends the call to the receptionist so they know what is going on.  This has been a problem when somebody in another office called 911 and nobody there was responding to messages, we had no idea what was going on.  Now the receptionist will be able to know what is going on in the event of a 911 call.

The Code:
exten => 911,1,GotoIf($["${CDR(SRC):0:2}"="10"]?sanmateo911)
exten => 911,n,GotoIf($["${CDR(SRC):0:2}"="11"]?makati911)
exten => 911,n,GotoIf($["${CDR(SRC):0:2}"="15"]?redmond911)
exten => 911,n,GotoIf($["${CDR(SRC):0:2}"="16"]?redmond911)
exten => 911,n,GotoIf($["${CDR(SRC):0:2}"="18"]?lacey911)
exten => 911,n,GotoIf($["${CDR(SRC):0:2}"="19"]?lacey911)
exten => 911,n(makati911),Playback(ss-noservice)
exten => 911,n,Hangup()
exten => 911,n(sanmateo911),System(/etc/asterisk/scripts/ "${CDR(SRC)}" "6505551212" "San Mateo")
exten => 911,n,Set(SPYGROUP=E911)
exten => 911,n,Set(CALLERID(all)=6505551212)
exten => 911,n,Dial(SIP/911@bandwidth-primary)
exten => 911,n,Hangup()
exten => 911,n(redmond911),System(/etc/asterisk/scripts/ "${CDR(SRC)}" "4255551212" "Redmond")
exten => 911,n,Set(SPYGROUP=E911)
exten => 911,n,Set(CALLERID(all)=4255551212)
exten => 911,n,Dial(SIP/911@bandwidth-primary)
exten => 911,n,Hangup()
exten => 911,n(lacey911),System(/etc/asterisk/scripts/ "${CDR(SRC)}" "2535551212" "Lacey")
exten => 911,n,Set(SPYGROUP=E911)
exten => 911,n,Set(CALLERID(all)=2535551212)
exten => 911,n,Dial(SIP/911@bandwidth-primary)
exten => 911,n,Hangup()

;the context that the call will be sent to to listen to the 911 call
exten => _1XXX,1,ChanSpy(SIP/${EXTEN},b)

And you can get the source for here, please note I added .txt to the extension so the server wouldn't try and parse it.

After you implement your 911 code it is very important that you make a test phone call from each location, tell the responder that the call is a non emergency test call and you would like to verify the address and phone number they received.  This way you know what you've done works properly before something that really needs 911 happens.


  1. Hi, I can't see your file, looks like the web server is still trying to process it. Can you post it here, or somewhere else, I'd be very interested to see it!

    Many thanks.

  2. great article andrew. i am thinking of doing the same but have couple of questions.
    1) who was your ITSP?
    2) how many SIP trunk did you buy for each DID you assigned to your three locations?

    1. 1) We use flowroute
      2) Flowroute does't charge 'per trunk' just by the minute for usage. We have an unlimited number of concurrent calls, and all calls go out the same trunk, and can send whatever we want for the callerid on any of them. If it's a 911 call we send the e911 DID for that location, otherwise we send our main company number.

  3. Are there any more effective solutions available now? If not I am interested in trying this on a new asterisk build. Are you able to upload the file someplace because your link is now dead. Thanks!

    1. Doh, unfortunately I don't have it anymore.

      It should be simple to write a script to do whatever you want in place of it (in our case it was a simple email to HR and the receptionists).