Greg's Blog
  • All posts

Asterisk quick startup - Sun, Nov 6, 2022

SIP and VoIP

Voice over IP is a standard for for communication over IP. It is used in a lot of applications, especially in recent communication software and aims at replacing RTC, traditional telephone lines. SIP is the protocol implementing a VoIP standard compatible with telephones, SIP client software and compatible phones. Asterisk is a software with a lot of capabilities, phone-book, voice mail and SIP server.

Prerequisites

VoIP implies an already working IP stack with a backbone IP network, DHCP if you want to and to open ports on the Asterisk host. The required port is 5060 on UDP for SIP but other ports are used for other services. You can use the net-tools netstat to see the ports in use with netstat -tunlp | grep asterisk

Asterisk vocabulary & principle

A lot of diagrams exist about Asterisk and while they are very complete, I find they often lack in clarity. Below is a lot of useful terms to get started with Asterisk for SIP phone call only. Asterisks uses its different capabilities in modules. The different modules of Asterisk are loaded automatically unless you specify noload in /etc/asterisk/modules.conf . The phone module that implements the SIP protocol is pjsip. It configuration is at /etc/asterisk/pjsip.conf.

pjsip.conf

Transport

The pjsip config file has objects of different types. But first of all, specify the sort of transport you want such as:

[transport-udp]
type=transport
protocol=udp    ;udp,tcp,tls,ws,wss,flow
bind=0.0.0.0

Endpoints

Endpoints are the phones that can be connected to this Asterisk server. You have to configure a couple of objects for each one, here is an example for a SIP phone:

[phony]
type=endpoint
transport=transport-udp
context=office-phones
disallow=all
allow=ulaw
auth=phony
aors=phony

[phony]
type=auth
auth_type=userpass
username=phony
password=REDACTED

[phony]
type=aor
max_contacts=1

[phony]
type=identify
match=192.166.0.0/24

This configuration defines the phony objects of different types: endpoint is the main objects and ties the different ones together. auth is the authentication method. I used a static one but an interesting future work would be to connect to a LDAP. AOR is an “Address of Record” and provides Asterisk with information about the endpoint connection. And identify is necessary to authorize the endpoint to connect from the IP range.

Extensions

So far, endpoints can connect by providing the SIP server IP, a username and password. But they don’t have a phone number yet. Asterisk calls these phone numbers extensions and they are defined in /etc/asterisk/extensions.conf

This is where the context part of the previous configuration (context=office-phones) is important. This is an example of configuration for internal communications:

[office-phones]
exten => 1001,1,Dial(PJSIP/phone1)
exten => 1002,1,Dial(PJSIP/phony)
exten => 1003,1,Dial(PJSIP/phone3)

exten => 9000,1,Answer()
same => n,Playback(hello-world)
same => n,Hangup()

the group [office-phones] shows what action is taken when a call is made from an endpoint of the office-phone context.

The general syntax is: exten => number,priority,action. Number is the actual phone number dialed. Priority is the order in which each action for a number is taken. Action is what to do. For example here, when the number 1002 is dialed by someone in the office-phone context, it dials to the phony endpoint. It of course fails if phony is not connected. The 9000 number is an example of programmatic answer: when 9000 is dialed, Asterisk Answers, Play the hello-world file and hangs up.

And… that’s it! With these configs you can call the different phones (endpoints) in office-phones. However, you still cannot call the outside world.

Dial Out

The “outside world” or as I call it the “default route” is called a SIP Trunk in the telecom context. At this point, you will need to pay for a SIP line to a provider. They are many of them, I use the VoIP from OVH as really cheap and I know the company.

The SIP company will provide you with a line number, password and SIP endpoint of the trunk. At this point, head back to pjsip.conf and use the config:

[mytrunk]
type=registration
outbound_auth=mytrunk
server_uri=sip:PROVIDER_SIP_URI
client_uri=sip:USERNAME@PROVIDER_SIP_URI
retry_interval=60

[mytrunk]
type=auth
auth_type=userpass
password=REDACTED
username=USERNAME

[mytrunk]
type=aor
contact=sip:PROVIDER_SIP_URI

[mytrunk]
type=endpoint
context=from-external
disallow=all
allow=ulaw
outbound_auth=mytrunk
aors=mytrunk

[mytrunk]
type=identify
endpoint=mytrunk
match=PROVIDER_SIP_URI

As you can see, we define a registration object for our trunk and an endpoint. With the trunk defined we need to be able to call number. Which means we need to define extensions in extensions.conf. We cant define an extension for every phone number in existence, but thankfully Asterisk supports pattern matching:

[toTheTrunk]
exten => _06XXXXXXXX,1,Dial(PJSIP/${EXTEN}@mytrunk)
exten => _0XXXXXXXXX,1,Dial(PJSIP/${EXTEN}@mytrunk)
exten => _+!,1,Dial(PJSIP/${EXTEN}@mytrunk

A number starting with an underscore means we use pattern matching, here the first two line are redundant but they mean to match all phone numbers with 10 digits starting in 06 and number with 10 digits starting with 0. Which is the standard over here. The last line matches the international format as we start with a + and ! means 1 or more digits. PJSIP/${EXTEN}@mytrunk means to dial the extension number we entered and to it via mytrunk which is the trunk we defined before.

We now just need to modify the previous configuration so that office phones can use the toTheTrunk extensions:

[office-phones]
include => toTheTrunk
exten => 1,1,Dial(PJSIP/phone)
exten => 2,1,Dial(PJSIP/phony)
exten => 3,1,Dial(PJSIP/phone3)

The include => toTheTrunk is used to include the extension we just made. And we can now make calls to the outside world. But, we still need to receive calls from the trunk.

Inbound Calls

The inbound calls part is pretty simple, we can use the from-external config element (we defined when creating our trunk) in the extensions:

[from-external]
exten => s,1,Dial(PJSIP/phone1)
exten => s,2,Dial(PJSIP/phone2)

This tells Asterisk to call phone1, then phone2 if phone1 is unreachable.

Back to Home


© WIN32GG 2022

Linkedin GitHub