Showing posts with label pjsip. Show all posts
Showing posts with label pjsip. Show all posts

Saturday, October 10, 2026

Some notes on SIPS schema on Asterisk

I was a bit surprised to find out, that SIPS does not mean SIP-over-TLS, but can be seen on plain UDP. So, if you have something like 

SIPS endpoint - Kamailio (TLS/UDP) - Asterisk (UDP)

you will have SIPS schema leftovers in Asterisk, for example in the Contact field, which is totally fine and legit. But the issue is that, on 200 - ACK answer sequence (which is a source of a majority of problems in SIP), Asterisk (or, rather PJSIP) looks at the Contact header with SIPS schema and tries to use TLS. This starts with Asterisk versions that use PJSIP 2.17, so from 20.12 and above.

There could be 2 solutions:

  • Clean/restore SIPS schema on Kamailio.
  • Compile PJSIP with PJSIP_DONT_SWITCH_TO_TLS 1 flag.

The easiest way is to use while compiling

./configure ... PJPROJECT_CFLAGS='-DPJSIP_DONT_SWITCH_TO_TLS=1'

but it's only for Asterisk 22.11+ or edit the file third-party/pjproject/patches/config_site.h

Update: seems to be, it's not enough. PJSIP will try to force TLS on BYE generating with SIPS schema. So, clean/restore on SIP Proxy than. Or avoid SIPS schema completely.

Tuesday, January 7, 2025

Asterisk PJSIP endpoint identification by To number

Recently got an interesting task.

For calls, that are made to a specific number, apply DTMF transcoding towards caller side. Means when someone (an automated system, actually) answers on this specific number, it starts send DTMF codes towards caller. But the main issue as, that callers, that are calling to this number accept DTMF only in inband mode, despite that looking on SIP traces they should accept usual RFC4733.

DTMF transcoding (in PJSIP) is handled by Asterisk via endpoint parameters. So, all calls ONLY to this number need to be put into a specific endpoint. Gladly, it's not so hard to achieve, but the documentation is lacking examples. So, here is the one:

pjsip.conf

[global]
...
# Depending on your configuration you might need to adjust the order
endpoint_identifier_order=ip,username,header,anonymous

# Actual endpoint we need call to be placed FROM
[test_endpoint]
type=endpoint
...
dtmf_mode=inband
identify_by=header

[test_endpoint]
type=identify
endpoint=test_endpoint
match_header=To:/123456789/

Now all calls made to a number, that consists sequence 123456789 will be made from test_endpoint and all DTMF towards this endpoint will be transcoded to inband.

Tuesday, November 28, 2023

Asterisk and sharing <Custom:> device states

Asterisk has a mechanism to sharing device states across the servers using just PJSIP.

But what is interesting, this mechanism is not really applies to Custom: device states. Means if you have 2 servers and want to share BLF state via hint and have something like

extensions.conf

...

exten => MY_STATE,hint,Custom:MY_DEVICE


and changing it via asterisk CLI


> devstate change Custom:MY_DEVICE BUSY


on the local server, it will change the hint on the remote server, but not the actual devstate that you're connecting this hint with 

> devstate list 

---------------------------------------------------------------------
--- Custom Device States --------------------------------------------
---------------------------------------------------------------------
---
--- Name: 'Custom:MY_DEVICE'  State: 'NOT_INUSE'
 

> core show hints

    -= Registered Asterisk Dial Plan Hints =-
MY_STATE@hints: Custom:MY_DEVICE  State:Busy            Presence:not_set         Watchers  0


This situation gives me a lot of hard times, when you have visual inconsistency on the same server, but totally forgetting that you have second spare server.

For me, the resolution was to sync the actual Custom: device states via external service using AMI that monitors DeviceStateChange events and using Setvar just changing the state explicitly.

Just a note, that if someone will fall into the same pit.

Thursday, September 21, 2023

Asterisk queues, local channels and transfers

Here comes the same old story about Asterisk queues and using Local channels within it. But with PJSIP flavour.

So, it is known, that local channels in Asterisk can be tricky and might require disable of the optimizations when used in Queues. Yes, famous /n at the end of the channel name so the Queue application can track the status of the channel

But the drawback of this method is also known and this is transfers calls from the agents. Means when you do a transfer, initial channel is not freed.

Or outgoing calls from the agents. Like if agent do an outbound call and still resides in a queue, it would not be considered as busy.

Many methods to workaround this, and I'm not exception to build own based on GROUP and GROUP_COUNT originating from Asterisk: The Definitive Guide book, but with some modifications regarding new ways of setting variables on PJSIP channels and further optimisations of Local Channel in the Asterisk.


queues.conf

...

[QUEUE_A]

member => Local/AGENT_A@agents

...

extensions.conf

...

[incoming]

exten => QUEUE_A,1,Queue(QUEUE_A)

[agents]

; First to  check if there are active calls on this agent

exten => AGENT_A,1,ExecIf($[ ${GROUP_COUNT(${EXTEN}@agents)} >= 1 ]?Congestion())

    ; We  need to set GROUP on outgoing channel as current channel will be destroyed upon answer

    same => n,Dial(PJSIP/AGENT_A@trunk,,b(set_group^${EXTEN}^1))

[agents_outgoing] 

; Make sure we're not getting calls to agent when it's on outgoing call

exten => OUT_NUM,1,Gosub(set_group,${CALLERID(num)},1)

    same => n,Dial(PJSIP/${EXTEN}@out_trunk)


[set_group]

exten => AGENT_A,1,Set(GROUP(agents)=${EXTEN})

    same => n,Return()

Just a small warning, it's more a pseudo-code, but just to give an overall idea