I am having Asterisk 16.30.0
installation in a EC2 instance.
Asterisk is installed using https://linuxhint.com/install-asterisk-ubuntu-22-04/
Below is the configuration for my Asterisk server running in EC2.
http.conf
[general]
enabled=yes
bindaddr=0.0.0.0
bindport=8088
tlsenable=yes
tlsbindaddr=0.0.0.0:8089
tlscertfile=/etc/asterisk/keys/asterisk.pem
sip.conf
[general]
tcpenable=yes
udpenable=yes
tcpbindaddr=0.0.0.0
udpbindaddr=0.0.0.0
bindaddr=0.0.0.0
bindport=5060
realm=127.0.0.1 ; replaced with static IP of EC2
transport=ws,wss
nat=yes
externip=127.0.0.1 ; replaced with static IP of EC2
media_address=127.0.0.1 ; replaced with static IP of EC2
directmedia=no
dtlsenable=yes
webrtc=yes
dtlssetup=actpass
rtcp_mux=yes
disallow=all
allow=ulaw,alaw
[friends_internal](!)
type=friend
host=dynamic
context=from-internal
transport=ws,wss
tcpenable=yes
nat=yes
avpf=yes
force_avp=yes
directmedia=no
qualify=yes
icesupport=yes
encryption=yes
dtlsenable=yes
dtlscipher=ALL
dtlsverify=fingerprint
dtlsverify=no
dtlscertfile=/etc/asterisk/keys/asterisk.pem
dtlsprivatekey=/etc/asterisk/keys/asterisk.pem
dtlssetup=actpass
rtcp_mux=yes
disallow=all
allow=alaw,ulaw
[1000](friends_internal)
username=1000
callerid=1000
secret=somepass
[2000](friends_internal)
username=2000
callerid=2000
secret=somepass
extension.conf
[default]
exten => 1000,1,Dial(SIP/1000)
exten => 2000,1,Dial(SIP/2000)
rtp.conf
[general]
rtpstart=10000
rtpend=20000
icesupport=yes
stunaddr=stun.l.google.com:19302
turnaddr=turn:myturnserver
turnusername=username
turnpassword=pass
The required keys are generated using the command.
./ast_tls_cert -C ec2-ip -O "ec2-ip" -d /etc/asterisk/keys
Required access provided to asterisk user to access keys.
The sip.js 0.16.0
client application running in a Google Chrome browser.
<!DOCTYPE html>
<head>
<script src="https://sipjs.com/download/sip-0.16.0.min.js"></script>
<script>
function sipTest() {
const userUri = SIP.UserAgent.makeURI("sip:1000@ec2-static-ip");
const userAgent = new SIP.UserAgent({
uri: userUri,
logLevel: "debug",
authorizationPassword: somepass,
authorizationUsername: '1000',
rel100: false,
hackViaTcp: false,
hackIpInContact: true,
hackWssInTransport: false,
transportOptions: {
traceSip: true,
server: "wss://ec2-static-ip:8089/ws"
},
delegate: {
onInvite,
onConnect,
onDisconnect
},
sessionDescriptionHandlerFactoryOptions: {
constraints: {
audio: true,
video: false
},
peerConnectionOptions: {
rtcConfiguration: {
iceServers: [
{
urls: "stun:stun.l.google.com:19302",
},
{
urls: "turn:myturn-server",
username: "username",
credential: "password",
}
],
},
},
},
});
const registerer = new SIP.Registerer(userAgent);
userAgent.start().then(() => {
console.log('UserAgent: start');
registerer.register();
});
// Setup myRegisterer state change handler
registerer.stateChange.addListener((newState) => {
switch (newState) {
case SIP.RegistererState.Registered:
console.log('Registered...');
break;
case SIP.RegistererState.Unregistered:
console.log('Unregistered...');
break;
case SIP.RegistererState.Terminated:
console.log('Terminated...');
break;
}
});
function onInvite(invitation) {
console.log('onInvite: invitation: ', invitation);
const callSession = invitation;
// Setup session state change handler
callSession.stateChange.addListener((state) => {
switch (state) {
case SIP.SessionState.Initial:
console.log('SessionState.Initial');
break;
case SIP.SessionState.Establishing:
console.log('SessionState.Establishing');
break;
case SIP.SessionState.Established:
console.log('SessionState.Established');
// We need to check the peer connection to determine which track was added
var pc = callSession.sessionDescriptionHandler.peerConnection;
console.log('PC: ', pc); // Valid
console.log('PC getReceivers: ', pc.getReceivers()); // Empty
console.log('PC getRemoteStreams: ', pc.getRemoteStreams()); // Empty
// Gets remote tracks
var remoteStream = new MediaStream();
pc.getReceivers().forEach(function(receiver) {
if (receiver.track) {
remoteStream.addTrack(receiver.track);
}
});
// I did try both the ways
const remoteAudio = new Audio();
// const remoteAudio = document.getElementById('remoteAudio');
remoteAudio.srcObject = remoteStream;
remoteAudio.play();
break;
case SIP.SessionState.Terminating:
case SIP.SessionState.Terminated:
console.log('SessionState.Terminated');
break;
default:
debugOut("Unknown session state.");
}
});
invitation.accept();
}
</script>
</head>
<body onload="sipTest()">
<audio id="remoteAudio"></audio>
</body>
</html>
Issues I am facing:
No audio is heard on both the ends.
On the client side:
When call is in SessionState.Established I get `pc.getRemoteStreams()` as empty and also `pc.getReceivers()` is empty in the Sip.js client.
And because of that I am not able to add streams to the Audio element.
On the server, I get below error after call is connected.
**When call is established and connected:**
WARNING[84463] chan_sip.c: Retransmission timeout reached on transmission xxxxxx-xxxxxxxx for seqno 123456789 (Critical Response) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions
Packet timed out after 31999ms with no response
WARNING[84463] chan_sip.c: Hanging up call xxxxxx-xxxxxxxx - no reply to our critical packet (see https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions).
**Also below errors:**
ERROR[92854] chan_sip.c: Serious Network Trouble; __sip_xmit returns error for pkt data
ERROR[92854] chan_sip.c: Serious Network Trouble; __sip_xmit returns error for pkt data
ERROR[92854] chan_sip.c: Serious Network Trouble; __sip_xmit returns error for pkt data
ERROR[92854] chan_sip.c: Serious Network Trouble; __sip_xmit returns error for pkt data
I have tested the stun and turn serves and they are appropriate resolution and I get relay server IP. Also EC2 instance security group provides access to all the UDP and TCP ports. For testing I have accepted the self signed certificate in using HTTPS Url from the browser where client app is running.