Migration of WCS4/Asterisk/MeetMe project to WCS5

marcw

Member
Hello!

A few years ago I set up a prank call project on a WCS4. Alex helped me to make some adjustments to bring my project to work. Now I must upgrade to WCS5 due to several reasons (i.E. Microsoft Edge and Firefox are not supporting any longer my project) and I need technical help. I set up a new server running CentOS 7.4, Asterisk 14.7.6 and WCS 5.0 so far but now I need to make the adjustments similar to the ones Alex did on my WCS4.

Below you can find the documentation I got from Alex regarded to the WCS4 adjustments and also to the project itsself. Especially I need to build again a custom handler jar file. I have the four old source files

InjectSoundObject.class
InjectSoundObject.java
WCS4PrankCallsHandler.class
WCS4PrankCallsHandler.java

but surely the content must be adjusted to fit WCS5. (I post the files or the content here if asked). Please help me to do so.

A second question: In the dependencies for the former WCS4 is written (also see below) that I need the "WCS 4 client API from branch 'wcs4_opus'". Which branch now it the matching one for WCS5?

Best regards
Marc

-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------

[ from the custom adjustment description of WCS4 ]

Project summary

Inject sound into telephone conversation, sound must be chosen at caller side.
Callee client should not hear caller as this can reveal caller.

Aims

Main aim is to have system for prank calls based on sound injection.

Software used

- Flashphoner WCS 4
- Asterisk 11.20.0

Main idea

WCS 4 is used for call initiation from Chrome or other WebRTC browser to SIP network. It uses WebRTC to deliver sound stream to caller and provides signaling to core. Caller can request custom functions through Websocket signaling from WCS 4 to trigger sound injection at core level. Asterisk is used as IP-PBX, it connects caller and callee parties into conference and plays sounds upon request.

Logic details

Chrome browser page uses WCS 4 client connecting to WCS 4 server and initiates call to "prank destination". WCS 4 sends SIP INVITE to Asterisk server. Asterisk writes callee number to a special variable "CONF" that will be used to create dynamic conference and then creates file with "CONF" variable in it. File name must be unique, Call-ID is used to name this file.
After this it initiates call to "prank destination" using Dial command with specially configured "G" option. When callee party answers a call Asterisk separates caller channel from callee channel and transfers them as follows:
1) caller channel transferred to context "separator" priority 1, and from where caller transferred to context "fun1"
2) callee channel transferred to context "separator" priority 2, and from where caller transferred to context "fun2"
In context "fun1" Asterisk shares "CONF" variable with callee channel and creates dynamic MeetMe conference. Caller enters this conference.
In context "fun2" Asterisk retrieves previously shared variable "CONF" end puts callee party into conference.
In this state there is active conference with caller and callee parties in it. Sound stream from caller is not participating in this conference (muted at conference level). Starting from this state caller can inject custom sound to conference. Chrome page as WCS 4 client sends request using function "sendData" to WCS 4. It transfers object with next fields:
{operationId:"inject",
payload:
{sound: playFile,
callId: currentCall.callId
}
};
Upon receiving such request WCS 4 tries to find file with conference number that Asterisk created at call initiation. If file is not found or conference number is not present in file WCS 4 gives error to log file and nothing happens. So, to trigger sendData function client must know Call-ID of active call. This gives some sort of security. After WCS 4 has conference number it creates Asterisk call file and puts it to spool directory. Asterisk initiates call to conference number and plays requested sound using call file. When played file ends Asterisk exits from conference.

How to use sendData function

At client API level sendData function has two arguments, callId:String and sound:String.
callId – Call-ID of current active call
sound – name of custom sound. Custom sounds must be known by Asterisk. Sounds can be placed in /usr/local/asterisk/var/lib/asterisk/sounds/en directory. It is possible to use multilevel directories for custom sounds. When you need to trigger sound located at /usr/local/asterisk/var/lib/asterisk/sounds/en with sound name all-circuits-busy-now.wav you need to pass:
sound = “all-circuits-busy-now”
If sound located at usr/local/asterisk/var/lib/asterisk/sounds/en/mysounds/taxes/you-have-new-bill.wav you need to pass:
sound =”mysounds/taxes/you-have-new-bill”

Dependencies

1) WCS 4 client API from branch "wcs4_opus"
http://flashphoner.com/downloads/builds/WCS/4.0/x8664/wcs4_opus/
2) Custom WCS4PrankCallsHandler with sendData method
3) Asterisk with dahdi timing and MeetMe app available

Hardcoded

1) Path to file with conference number
/usr/local/asterisk/var/lib/asterisk/conferences
2) Path to asterisk spool directory
/usr/local/asterisk/var/spool/asterisk/outgoing



-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------

Custom Handler for WCS4

Build JAR file

You need to execute build_jar.sh in /tmp directory to build JAR-file. Output file (marcophono.jar) will be in /tmp/com/marcophono/handler/. build_jar.sh has some variables inside:

TMP_DIR="/tmp"
SRC_DIR="com/marcophono/handler"
JAVA_BIN_DIR="/usr/java/jdk1.8.0_65/bin"

All java-files should be placed in SRC_DIR. After building jar-file should be copyed to /usr/local/FlashphonerWebCallServer/lib

Deploying JAR

1. Login to server through SSH to access CLI:
ssh -p 2000 admin@localhost

password: admin
2. Update default application with "defaultApp"-name, change main class for direct calls and URL:

update app --url "http://localhost/defaultApp" -m com.flashphoner.server.client.handler.custom.WCS4PrankCallsHandler defaultApp

Create defaultApp with httpd (apache)

1. Untar /root/defaultApp.tar.gz to /var/www/html
tar -zxvf /root/defaultApp.tar.gz -C /var/www/html
2. Change credentials in /var/www/html/defaultApp/connect.json as you need:
"sipLogin" : "test",
"sipAuthenticationName" : "test",
"sipDomain" : "127.0.0.1",
"sipOutboundProxy" : "127.0.0.1",
"sipPassword" : "TopSecret",
3. Try to call from web. Go to http://144.xx.xx.xx/defaultApp/. Set SIP callee and Sound fields and click "call".

Asterisk

Asterisk installed to /usr/local/asterisk directory. Config files accessible from /etc/asterisk.





How to use sendData

Use injectSound function from /var/www/html/defaultApp/Phone-min.js

function injectSound() {
var playFile = document.getElementById('sound').value;
var data = {operationId:"inject",payload:{sound:playFile,callId:currentCall.callId}};
f.sendData(data);
}
 

Max

Administrator
Staff member
Hello
There are two general steps you have to do.

1. Test a simple call with WCS5 and your application.
Just install WCS5 on another server and try to make a voice call to your conference.
Here you can find Phone demo sample:
https://demo.flashphoner.com/client2/examples/demo/sip/phone/phone.html
Make sure the call is established and you can hear one-way voice (from callee towards your web or mobile app).

2. Once your call is successfully established, try to manage Asterisk directly by manual copying call files.
1. Find conference ID:
Code:
cat /usr/local/asterisk/var/lib/asterisk/conferences/{callID}
here callID is id of established call.
2. Once you know the conference ID you can place a call file to inject sound into the conference.
Write file {callID}.call
Code:
Example:
Channel: Local/s@inject-sound
Application: Playback
Data: mypizzasound
Archive: Yes
Set: CONF={confID}
Here
mypizzasound - is existing wav file mypizzasound.wav
{confId} - is ID of your conference.
3. Place the callfile into the Asterisk directory.
Code:
cp {callID.call} /usr/local/asterisk/var/spool/asterisk/outgoing
Once you copied call file to the folder, Asterisk should make outgoing call into the conference and your case should work.
Therefore, you can try to make these all manually, and if it works in manual mode, you can think how to get this automatic.

3. If all works in manual mode, you can write a PHP script which will:
1) Parse conference ID.
2) Create call file.
3) Copy the call file to Asterisk folder.

Eventually you don't need to extend WCS server. You just need to parse file and copy callfile to Asterisk dir.
 

marcw

Member
Okay, I tried an initial test sip call as you mentioned and it failed. So it was a very good idea from you to let me check that first. :)
I had set up that sip phone example on my own server and entered my own values. Registering process worked fine. Also the callee phone ringed. Picking up let the flashphoner log show the correct entry "ESTABLISHED". All works but the audio was not played back on the browser. I fried it with Chrome and Firefox. May be a look into the attached flashphoner log can help?
By the way: A test call from your posted website (https://demo.flashphoner.com/client2/examples/demo/sip/phone/phone.html) with my sip account values and your given wss link let correctly register but the entered phone number's device never ringed.
Best regards
Marc
 

Attachments

Max

Administrator
Staff member
Hello
Try to add setting:
Code:
rtp_force_synchronization=true
in WCS_HOME/conf/flashphoner.properties then restart wcs server and repeat your test
 

marcw

Member
Damn, that works! :) Just wondering if that is the solution or a workaround? There will be a reason that this setting is not implemented by default. But what can be the reason that my server is a trouble maker for rtp synchronization if WCS5 is running in default setup? It is a high performance server, brand new set up and located in a german data center with extremly good connectivity. The workaround is absolute good enough as far as it works without any disadvantages but I am curious about the technical background.
Best
Marc
 

marcw

Member
Celebrated a bit too early. Now I have another problem which also occured yesterday from time to time. Now the call does not happen at all. In the cdr log I find
Code:
marcwaesche;00491777000001;2fa24880-5dd2-11e8-9c23-7d928ed4ba48;2018-05-22 17:09:55;;2018-05-22 17:10:10;0;NO_ANSWER;Failed by ICE error;/178.200.17.160:64947/195.201.166.182:8443
What can that point to?

Best
Marc
 

Max

Administrator
Staff member
Hello
WCS can be integrated with various software and hardware such as SIP servers, SIP proxy, conference servers, IP cams, RTSP servers and so on.
There are two types of software / hardware
1) Supports RTCP protocol.
Code:
rtp_force_synchronization=false (default)
2) Do not support RTCP protocol.
Code:
rtp_force_synchronization=true
It seems your conference server does not support RTCP protocol and does not send RTCP packets.
That's why it works if you set the setting to true.
RTCP protocol is used for synchronization between audio and video tracks.
If you don't have video tracks, then the setting is a solution for you. Not a workaround.
Though it looks like a bug on our end too. We have to detect if RTCP is supported and we should not ask users to change server-side settings.
 

marcw

Member
Oh, okay. Didn't know that there is something like a conference server available. :)
But don't I need a conference server anyway? I think I have a general understanding issue. The test website you initially posted to me, and which I also set up on my own server, doesn't use my Asterisk server on the same machine. So I also cannot find any generated call files in the conference folder. Is it up to me to "connect" the WCS with Asterisk? Or is there another test client available where a call is managed through my Asterisk?

Best
Marc

P.S.: I hope you didn't miss my last post here. I sent it nearly in the same second than you sent your answer to the post before my last one. So may be you missed it due to that timing. I made some more tests now. Sometimes it works, sometimes not. If not I can see in the console that the status stays at "pending" and after awhile it falls back to "finished". Then I can find the ICE error in my logs.

Code:
marcwaesche;00491777000001;06c98180-5df5-11e8-8401-51b72ed18108;2018-05-22 21:19:19;;2018-05-22 21:19:34;0;NO_ANSWER;Failed by ICE error;/178.200.17.160:63029/195.201.166.182:8443
marcwaesche;00491777000001;16cd15b0-5df5-11e8-8401-51b72ed18108;2018-05-22 21:19:46;2018-05-22 21:19:48;2018-05-22 21:19:56;8;NO_ANSWER;Normal call clearing;/178.200.17.160:63114/195.201.166.182:8443
marcwaesche;00491777000001;a112e1a0-5df5-11e8-8401-51b72ed18108;2018-05-22 21:23:38;2018-05-22 21:23:41;2018-05-22 21:23:46;4;NO_ANSWER;Normal call clearing;/178.200.17.160:63817/195.201.166.182:8443
marcwaesche;00491777000001;b1b91e70-5df5-11e8-8401-51b72ed18108;2018-05-22 21:24:06;2018-05-22 21:24:09;2018-05-22 21:24:13;3;NO_ANSWER;Normal call clearing;/178.200.17.160:63904/195.201.166.182:8443
marcwaesche;00491777000001;bf06ba60-5df5-11e8-8401-51b72ed18108;2018-05-22 21:24:28;2018-05-22 21:24:32;2018-05-22 21:24:38;6;NO_ANSWER;Normal call clearing;/178.200.17.160:63992/195.201.166.182:8443
marcwaesche;00491777000001;d13e93b0-5df5-11e8-8401-51b72ed18108;2018-05-22 21:24:59;;2018-05-22 21:25:14;0;NO_ANSWER;Failed by ICE error;/178.200.17.160:64076/195.201.166.182:8443
And here from the client log for one of the failed calls:
Code:
21:24:55,190 INFO     AbstractWCSClient - API-ASYNC-pool-23-thread-27 Create custom Softphone instance for marcwaesche
21:24:59,395 INFO              IceAgent - API-ASYNC-pool-23-thread-29 Create custom STUN agent: RTC-d13e93b0-5df5-11e8-8401-51b72ed181087fi631ce4kvk43
21:24:59,395 INFO              IceAgent - API-ASYNC-pool-23-thread-29 Create custom STUN media stream: audio
21:24:59,395 INFO             Component - API-ASYNC-pool-23-thread-29 Component created, start socket: 31094
21:24:59,395 INFO    StunDatagramSocket - API-ASYNC-pool-23-thread-29 Create UDP socket on port 31094
21:24:59,397 INFO    AbstractRtpSession - API-ASYNC-pool-23-thread-29 Create Rtp Session - /195.201.166.182:31090 - /195.201.166.182:31091
21:25:14,413 INFO    StunDatagramSocket - Stun receiver udp/31094 Stun freshness timeout is over: call setState listener on Agent:214 - KEEP_ALIVE_FAILED
21:25:14,413 INFO              IceAgent - Stun receiver udp/31094 Change agent state to: KEEP_ALIVE_FAILED
21:25:14,414 INFO       RtcMediaSession - Stun receiver udp/31094 propertyChange Agent for id = RTC-d13e93b0-5df5-11e8-8401-51b72ed18108 entered the Failed by ICE keep alive state.
21:25:14,415 INFO          MediaSession - Stun receiver udp/31094 Stop MediaSession id: RTC-d13e93b0-5df5-11e8-8401-51b72ed18108
21:25:14,415 INFO      ProxyMediaClient - Stun receiver udp/31094 Stop, subscribers size 0
21:25:14,415 INFO              IceAgent - Stun receiver udp/31094 Release agent RTC-d13e93b0-5df5-11e8-8401-51b72ed181087fi631ce4kvk43, free all resources
21:25:14,415 INFO          MediaSession - Stun receiver udp/31094 Stop MediaSession id: d13e93b0-5df5-11e8-8401-51b72ed18108
21:25:14,416 INFO    AbstractRtpSession - Stun receiver udp/31094 RtpSession with id d13e93b0-5df5-11e8-8401-51b72ed18108 terminated.
21:25:14,416 INFO      ProxyMediaClient - Stun receiver udp/31094 Stop, subscribers size 0
 
Last edited:

Max

Administrator
Staff member
Hello
Try to add setting:
Code:
stun_freshness_timeout=1000000000
in flashphoner.properties
But don't I need a conference server anyway?
You need two logical servers 1) WCS 2) Asterisk+conference.
These two servers can be either 1) located on the same server or 2) on two different servers
WCS communicates with Conference over SIP/RTP protocols.
So if WCS and Conference server are deployed on two different machines, the simple calls should work out of the box.
Make sure the simple calls work for you.
Then follow step 2 to manage Asterisk callfiles.
 

marcw

Member
Hi Max!
I added it and restarted the WCS but the problem still exists. From time to time, especially when I do not use the WCS for a few minutes, the calls fail. I have attached all logs related to the failed call.
But just to make sure I want to repeat it: I have Asterisk installed on the same server BUT while doing the test calls via the client on examples/demo/sip/phone/phone.html my Asterisk is not in any use. I just point to it because you said that I shall get the conference ids my Asterisk is dynamically creating but that cannot work as far as I use the client at examples/demo/sip/phone/phone.html. My test calls (sometimes) work because I entered the access data of my VOIP provider into the client mask.

Best
Marc
 

Attachments

Max

Administrator
Staff member

Attachments

marcw

Member
Hi Max!
Great, it is working now! Really happy! :) Yesterday I was playing around with the conference room and all worked fine so far since I made a server reboot. Since that the WCS isn't working any longer. I think I had installed a lot of tools/updates the last days and one of them seems to have effect since the reboot. I tried reinstalling the WCS, installing a different JDK version and a lot of other things but now after around 15 hours I have no other idea. I was very close to setup the whole server from the scratch but then the effect could happen again. May be you have an idea. I added the log from the last WCS installation. Seems that the database driver had some issues. And yes, I also tried to remove the two databases.
CentOS 7.4
JDK 1.8.0_171 (and later another test with 161)
nginx and php-fpm

Best
Marc
 

Attachments

Max

Administrator
Staff member
Hello
From logs we can see show stopper is port binding error
Code:
23:56:06,282 ERROR         SSHLifeCycle - main Could not start CRaSSHD
java.net.BindException: Address already in use
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:433)
    at sun.nio.ch.Net.bind(Net.java:425)
It is built-in WCS SSH server for CLI. Make sure port 2000 TCP is not busy.
If it is bound by another app, try to release this port.
 

marcw

Member
Indeed, port 2000 was binded to the Asterisk skinny module. I excluded it with noload => chan_skinny.so in the modules.conf, restarted Asterisk and WCS and that error is gone. But it is still not working. When just trying to connect via the test app website nothing happened in the flashphoner_manager logs.
Logs (flashphoner_manager and used ports) attached.

Best Marc
 

Attachments

Max

Administrator
Staff member
Hello
Server looks healthy. Check ports 8443, 8888. Make sure it is open.
Try to disable firewall if it is running.
Code:
telnet host 8443
telnet host 8888
 
Top