How to change the Hello World Asterisk example to use TCP instead of UDP?

I setup Asterisk on a server. I set up the basic “Hello, World” example (direct from the docs here) which entails having my extensions.conf file as:

[from-internal]
exten = 100,1,Answer()
same = n,Wait(1)
same = n,Playback(hello-world)
same = n,Hangup()

and my pjsip.conf file as:

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

[6001]
type=endpoint
context=from-internal
disallow=all
allow=ulaw
auth=6001
aors=6001

[6001]
type=auth
auth_type=userpass
password=unsecurepassword
username=6001

[6001]
type=aor
max_contacts=1

I have a simple Python script to make a call to the extension 100. This is direct from the docs here, where I call this script passing in the sip address sip:100@:

import sys
import pjsua as pj

# Logging callback
def log_cb(level, str, len):
    print str,

# Callback to receive events from Call
class MyCallCallback(pj.CallCallback):
    def __init__(self, call=None):
        pj.CallCallback.__init__(self, call)

    # Notification when call state has changed
    def on_state(self):
        print "Call is ", self.call.info().state_text,
        print "last code =", self.call.info().last_code, 
        print "(" + self.call.info().last_reason + ")"

    # Notification when call's media state has changed.
    def on_media_state(self):
        global lib
        if self.call.info().media_state == pj.MediaState.ACTIVE:
            # Connect the call to sound device
            call_slot = self.call.info().conf_slot
            lib.conf_connect(call_slot, 0)
            lib.conf_connect(0, call_slot)
            print "Hello world, I can talk!"


# Check command line argument
if len(sys.argv) != 2:
    print "Usage: simplecall.py <dst-URI>"
    sys.exit(1)

try:
    # Create library instance
    lib = pj.Lib()

    # Init library with default config
    lib.init(log_cfg = pj.LogConfig(level=3, callback=log_cb))

    # Create UDP transport which listens to any available port
    transport = lib.create_transport(pj.TransportType.UDP)

    # Start the library
    lib.start()

    # Create local/user-less account
    acc = lib.create_account_for_transport(transport)

    # Make call
    call = acc.make_call(sys.argv[1], MyCallCallback())

    # Wait for ENTER before quitting
    print "Press <ENTER> to quit"
    input = sys.stdin.readline().rstrip("\r\n")

    # We're done, shutdown the library
    lib.destroy()
    lib = None

except pj.Error, e:
    print "Exception: " + str(e)
    lib.destroy()
    lib = None
    sys.exit(1)

This all works fine, I call the SIP server, and hear the “Hello, World” recording.

What do I need to change so that I can have this communication occur over TCP? So far I have tried changing my pjsip.conf file by changing the protocol to tcp in the following part:

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

, adding ;transport=tcp to the URI of my server that I pass in to the Python script, and also changing the line in the Python script that creates a Transport to

# Create UDP transport which listens to any available port
transport = lib.create_transport(pj.TransportType.UDP)

What happens is in the Python script I get

pjsua_acc.c !...SIP registration failed, status=408 (Request Timeout)

And on the server I don’t see the request at all.

Changing the “protocol” to “tcp” on the Asterisk side will have it listen to TCP. As for the pjsua side, I don’t have experience there.

I have a feeling this might be related to me being behind a NAT. In this case it appears it would not be as simple as changing the protocol to tcp, correct? The PJSUA side is working fine actually, at least I can see the SIP REGISTER message being sent. It isn’t reaching the server however.

Which is behind NAT? If Asterisk is behind NAT you need to ensure that the port is opened and that the options for NAT are set[1]. If the remote is behind NAT you need to ensure the options for that are set (rewrite_contact and rtp_symmetric).

[1] https://wiki.asterisk.org/wiki/display/AST/Configuring+res_pjsip+to+work+through+NAT

I am not yet sure, I am new to this networking stuff, and am in the process of finding out.

A question: does it make sense that if I am having issues with TCP communication with Asterisk due to the presence of NAT, that I don’t have the issues when I use UDP?

It is possible, yes. Without knowing the network layout it’s impossible to say with certainty where the problem areas would be.