Moving from chan_sip to pjsip

Who am I?

Tom De Moor

@ctl_alt_dieliet

Belgium


Developer

Twitter-app for the Digium phones
LDAP-addressbook for the Digium phones

Find them on http://www.asteriskexchange.com

Examples

Find them at: http://www.controlaltdieliet.be/astricon2015/

chan_sip or res_pjsip?

chan_sip or res_pjsip?

chan_sip or res_pjsip?

chan_sip or res_pjsip?

What is wrong with chan_sip?

What is wrong with chan_sip?

  • Nothing?!
  • Has been modified alot
  • Hard to maintain
  • Slowing down further development

PJSIP?

Why is res_pjsip better?

  • Better configuration
  • Multiple aors for same endpoint
  • NAT is less obscure
  • No user,peer,friend
  • Better device and mailbox state
  • Easier, faster and better development
  • => It is the future!

Can I run them together?

  • Yes!
  • Different port or ip
  • patch for websockets

Configuration

  • Try to forget chan_sip
  • Not a 1 to 1 relationship

Chan_sip basic config

[general]
udpbindaddr=0.0.0.0

[6001]
type=friend
host=dynamic
disallow=all
allow=ulaw
context=internal
secret=1234

PSJIP basic config

[simpletrans]
type=transport
protocol=udp
bind=0.0.0.0

[6001]
type = endpoint
transport = simpletrans
context = internal
disallow = all
allow = ulaw
aors = 6001
auth = auth6001

[6001]
type = aor
max_contacts = 1

[auth6001]
type=auth
auth_type=userpass
password=1234
username=6001

Res_pjsip config types

  • Transport "transport"
  • Endpoint "endpoint"
  • Authentication "auth"
  • Address of Record "aor"
  • Endpoint Identification "identify"
  • Registration "registration"
  • Access Control List "acl"
  • Phone Provisioning "phoneprov"
  • System
  • Domain_alias
  • outbound-publish

Templates and wizards

  • [name]
  • Type=
  • Option=value
  • Templates (!)
  • Wizards

Transport

Transport

  • Binds res_pjsip to an address and a port.
  • Multiple bindings are possible
  • Can't reload during runtime
  • Transport: minimal config

    [smallest]
    type=transport
    protocol=udp
    bind=0.0.0.0

    Transport: more config

    [more_complex]
    type=transport
    protocol=udp,tcp,tls,ws,wss
    bind=0.0.0.0:5061
    local_net=192.0.2.0/2
    external_media_address=20.0.113.1
    external_signaling_address=20.0.113.1

    Endpoint

    A device that sends/receives calls
    • transport
    • AOR
    • auth

    Endpoint

    [6001]
    type=endpoint
    context=default
    disallow=all
    allow=ulaw
    transport=simpletrans
    auth=auth6001
    aors=6001

    AOR: location

    • Multiple AORS for 1 device!
    • AORS can be overwritten or not
    • Can be static or dynamic (qualify)

    AOR: Static

    [6001]
    type=aor
    contact=sip:6001@192.0.2.1:5060
    contact=sip:6001@192.0.2.2:5060

    AOR: Dynamic

    [aor]
    type=aor
    default_expiration=3600
    maximum_expiration=7200
    minimum_expiration=60
    max_contacts=1
    remove_existing=yes
    qualify_frequency=60
    qualify_timeout=3.0

    Auth: Password please

    Options /settings for inboud or outbound registration

    Auth: Password please

    [auth6001]
    type=auth auth_type=userpass
    password=secret
    username=6001

    Registration: Plugging your asterisk into the matrix

    Connecting your Asterisk to another Asterisk
    Used to be:
    register =>username:password@server/context

    Registration: example

    [mytrunk]
    type=registration
    transport=simpletrans
    outbound_auth=mytrunk
    server_uri=sip:sip.example.com
    client_uri=sip:1234567890@sip.example.com
    retry_interval=60

    Identify: Can we some some id please

    IP-based authentication
    Matches incoming packets => endpoint
    Looks at on source IP adress

    Optional!
    res_pjsip_endpoint_identifier_user pulls the user from the "From:" SIP header
    The module load order and your configuration will both determine whether you identify by IP or by user (res_pjsip_endpoint_identifier_ip loading after res_pjsip_endpoint_identifier_user)

    Identify:example

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

    Bringing it all together!

    NAT-endpoint

    [transport-udp-nat]
    type=transport
    protocol=udp
    bind=0.0.0.0
    local_net=192.0.2.0/24
    external_media_address=203.0.113.1
    external_signaling_address=203.0.113.1

    [auth6001]
    type=auth
    auth_type=userpass
    password=1234
    username=6001

    [6001]
    type = endpoint
    transport = transport-udp-nat
    context = internal
    disallow = all
    allow = ulaw
    aors = 6001
    auth = auth6001
    direct_media=no
    [6001] type = aor
    max_contacts = 2

    NAT-TRUNK

    [mytrunk]
    type=registration
    transport=simpletrans
    outbound_auth=mytrunk
    server_uri=sip:sip.example.com
    client_uri=sip:1234567890@sip.example.com
    retry_interval=60
    auth_rejection_permanent = no
    retry_interval = 30
    forbidden_retry_interval = 300
    max_retries = 20
    [mytrunk] type=auth
    auth_type=userpass
    password=1234567890
    username=1234567890
    [[mytrunk]
    type=endpoint
    transport=simpletrans
    context=from-external
    disallow=all
    allow=ulaw
    outbound_auth=mytrunk
    aors=mytrunk
    [mytrunk] type=identify
    endpoint=mytrunk
    match=203.0.113.1
    [mytrunk]
    type=aor
    contact=sip:203.0.113.1:5060

    Wizards!

    [my-itsp]
    type = wizard
    sends_auth = yes
    sends_registrations = yes
    remote_hosts = sip.my-itsp.net
    outbound_auth/username = my_username
    outbound_auth/password = my_password
    endpoint/context = default
    aor/qualify_frequency = 15

    The dialplan

    exten => _6XXX,1,Dial(PJSIP/${EXTEN}) (dials first contact)

    exten => _6XXX,1,Dial(${PJSIP_DIAL_CONTACTS(${EXTEN})})

    exten => _9NXXNXXXXXX,1,Dial(PJSIP/${EXTEN:1}@mytrunk)

    exten => _9NXXNXXXXXX,1,Dial(PJSIP/mytrunk/sip:${EXTEN:1}@203.0.113.1:5060)

    Those little differences

    same => n,Dial(PJSIP/Agent1,,b(set_header^s^1))

    [set_header]
    exten => s,1,Set(PJSIP_HEADER(add,X-My-DNID2)=${MY_DNID})
    same => n,Return


    ${SIPPEER(${peer},status)} for PJSIP?

    DEVICE_STATE(PJSIP/endpoint)

    Realtime

    • Alembic
    • Many tables
      • ps_aors
      • ps_auths
      • ps_contacts
      • ps_endpoints
      • ps_domain_aliases
      • ps_endpoint_id_ips
      • ps_endpoints
      • ps_globals
      • ps_registrations
      • ps_subscription_persistence
      • ps_systems
      • ps_transports

    sorcery.conf

    ps_endpoints => odbc,asterisk
    ps_auths => odbc,asterisk
    ps_aors => odbc,asterisk
    ps_domain_aliases => odbc,asterisk
    ps_endpoint_id_ips => odbc,asterisk
    ps_contacts => odbc,asterisk

    extconfig.conf

    ps_endpoints => odbc,asterisk
    ps_auths => odbc,asterisk
    ps_aors => odbc,asterisk
    ps_domain_aliases => odbc,asterisk
    ps_endpoint_id_ips => odbc,asterisk
    ps_contacts => odbc,asterisk

    Filling it up with data!

    Good news!

    I've made a script for that!
    Download it from
    http://www.controlaltdieliet.be/astricon2015/