Need help with dealing with multiple physical locations and 911

Hello. I am very new to freepbx/asterisk and could use some help.
I have 13 different locations, all spread out across town…some in neighboring towns.
I have a single asterisk server and providers located at our main office that servers them all.
There is not extension standard or pattern. users will regularly move offices, taking their phone/extension with them.
This is causing a big headache when 911 has been dialed, as the call is being routed to the wrong 911 dispatch.
I can designate a cid for each location with the provider, so no problem there. I think the most consistent way to address this would be by endpoints IP address/locations subnet. It looks like res_pjsip_endpoint_identifier_ip will get me the IP of the endpoint.
My problem is that I have no idea how to use it nor change the CID based on the IP when 911 is called.

Any help would greatly be appreciated.

I replied in your thread on the Asterisk Community with some smaple code that should get you close.


We’ve actually been helping people with E911 problems like these for the past couple of years. Having an automated solution can make your life less hectic - just be sure it’s working correctly.

As far as setting the CID for the extensions goes, there are lots of ways to handle that in FreePBX. If you get yourself stuff, ask and we should be able to help you get back on track.

thanks @sorvani and @cynjut

I’m pretty much stuck on all of this. If its not in the gui, then I’m in trouble! haha. I’m very new at asterisk and freepbx.

My next topic will probably be asking for recommendations on professional services to build a gui/module so that this is made easier for anyone on my team to make changes or additions (or for the next guy that comes behind me).

@sorvani @cynjut
Im going to need some hand holding. Id gladly pay for professional services to get this right. let me know via DM if either of you are interested

Realistically, each location needs to be able to register it’s E911 location. As such, each location needs it’s own outbound and inbound route, complete with designation as to which one handles emergency routing.

Yes. That is what he wants to do, by IP address of the devices. Because his extensions are all mixed around, there is no “simple” method with a basic dial pattern rule that includes the CID.

Thanks for pointing me in the right direction. I think I have figured out a working solution now!
Thanks again

Care to share it with us?

I’m sure there is a cleaner/better way, but this is what I have come up with for now. Hopefully I can improve on it…would love any suggestions.

exten => s,1,NoOp()
exten => s,n,GotoIf($[${CALLERID(dnid)}=911]?s_CID_OVERRIDE,1:)
exten => s_CID_OVERRIDE,1,NoOp()
exten => s_CID_OVERRIDE,n,Set(endpoint_addr=${CHANNEL(pjsip,remote_addr)})
exten => s_CID_OVERRIDE,n,Set(ip_addr=${CUT(endpoint_addr,:,1)})
exten => s_CID_OVERRIDE,n,Set(CALLERID(num)=${IF($[192.168.100.[0-9] = ${ip_addr}]?5551231111)})
exten => s_CID_OVERRIDE,n,Set(CALLERID(num)=${IF($[192.168.200.[0-9] = ${ip_addr}]?5551232222)})
exten => s_CID_OVERRIDE,n,Set(CALLERID(num)=${IF($[192.168.300.[0-9] = ${ip_addr}]?5551233333)})
1 Like

Instead of checking the value of CALLERID(dnid) check instead for the value of EMERGENCYROUTE it will == ‘YES’ for calls that are using an outbound route that is marked emergency. There is also the (admittedly rare) possibility that a call might be directed to 911 that does not have dnid set as expected. It will also allow you to test your emerg calls without dialing 911 if your provider supports it.

You’re assuming the outbound channel is PJSIP, make sure it won’t interfere with outbound dialing for other channel types that might crop up in the future. You do not want to learn the hard way that an outbound emerg call failed. You can employ a check for channel type see the context from-pstn-toheader

Otherwise very elegant

1 Like

yes… @sorvani suggested to use EMERGENCYROUTE as well, but I went with the callerid, so I could test it with any number dialed…I will go back and change that! All of our extensions are configured for pjsip, but you bring up a very good point! I will do some more reading for that! :slight_smile:

Your first go to needs another destination if it is not a match

1 Like

Thanks. I’ll add that. I thought that since there was no match, it would just go to the next operation within the extension. since there was not one, it would just finish out. My test seemed to indicate that was the case, but I guess that’s not best practices?

gotcha…that seems like a pretty easy to add. While looking at the context, I kinda went down the rabbit hole a bit. I see that I can get the endpoint IP from the SIP HEADERS too. Is one method better than the other (IP from channel vs headers)?

EDIT The previous version of didn’t work the way I had hoped. I have changed it. I have edit this post with the new version.
This is what I have worked out…is it too much? Would love additional feedback…thanks again…I feel like im starting to wrap my head around some of this! :slight_smile:

exten => s,1,NoOp()
exten => s,n,GotoIf($[$["${CALLERID(dnid)}" = "911"] | $["${EMERGENCYROUTE}" = "YES"]]?s_CHANNLE_TYPE,1:s_exit,1)

exten => s_CHANNLE_TYPE,1,NoOp()
exten => s_CHANNLE_TYPE,n,GotoIF($["${CHANNEL(channeltype)}" = "PJSIP"]?s_PJSIP_IP,1)
exten => s_CHANNLE_TYPE,n,GotoIF($["${CHANNEL(channeltype)}" = "SIP"]?s_SIP_IP,1)
exten => s_CHANNLE_TYPE,n,Log(NOTICE, <Emergency CID OVERRIDE> Unable to get channel type. CID-IP Mapping not used.)
exten => s_CHANNLE_TYPE,n,Goto(s_exit,1)

exten => s_PJSIP_IP,1,NoOp()
exten => s_PJSIP_IP,n,Set(endpoint_addr=${CHANNEL(pjsip,remote_addr)})
exten => s_PJSIP_IP,n,Set(ip_addr=${CUT(endpoint_addr,:,1)})
exten => s_PJSIP_IP,n,GotoIF($ ["${ip_addr}" != ""]?s_CID_IP_MAP,1)
exten => s_PJSIP_IP,n,Log(NOTICE, <Emergency CID OVERRIDE> Unable to get endpoint ip from PJSIP channel. CID-IP Mapping not used.)
exten => s_PJSIP_IP,n,Goto(s_exit,1)

exten => s_SIP_IP,1,NoOp()
exten => s_SIP_IP,n,Set(ip_addr=${CHANNEL(sip,peerip)})
exten => s_SIP_IP,n,GotoIF($ ["${ip_addr}" != ""]?s_CID_IP_MAP,1)
exten => s_SIP_IP,n,Log(NOTICE, <Emergency CID OVERRIDE> Unable to get endpoint ip from SIP channel. CID-IP Mapping not used.)
exten => s_SIP_IP,n,Goto(s_exit,1)

exten => s_CID_IP_MAP,1,NoOp()
exten => s_CID_IP_MAP,n,GoSubIF(${REGEX("(192\.168\.7\.[0-9])" ${ip_addr})}?s_SetCID,1(5551117777)) ;location1
exten => s_CID_IP_MAP,n,GoSubIF(${REGEX("(192\.168\.8\.[0-9])" ${ip_addr})}?s_SetCID,1(5551118888)) ;location2
exten => s_CID_IP_MAP,n,GoSubIF(${REGEX("(192\.168\.9\.[0-9])" ${ip_addr})}?s_SetCID,1(5551119999)) ;location3
exten => s_CID_IP_MAP,n,GoSubIF(${REGEX("(192\.168\.0\.[0-9])" ${ip_addr})}?s_SetCID,1(5551110000)) ;location4
exten => s_CID_IP_MAP,n,Log(NOTICE, <Emergency CID OVERRIDE> Unable to find CID mapping for ${ip_addr} . CID-IP Mapping not used.)
exten => s_CID_IP_MAP,n,Goto(s_exit,1)

exten => s_SetCID,1,NoOp()
exten => s_SetCID,n,Set(CALLERID(num)=${ARG1})   
exten => s_SetCID,n,Goto(s_exit,1)

exten => s_exit,1,NoOP()
exten => s_exit,n,MacroExit()
1 Like

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