Posts Tagged freeswitch

End-to-end VoIP quality testing probes

This is a result of a project where we needed to measure voice QoS parameters (jitter and packet loss) in the customer network. I’ve set up small probe computers (old 10″ Intel Atom netbooks like Acer Aspire One) with FreeSWITCH and a few scripts for test automation. Each test consists of a 30-second call (producing approximately 1500 RTP packets in each direction), and tshark is measuring the received jitter and loss on each side.

Test details and the installation procedure are outlined on Github:

https://github.com/xlab1/voip_qos_probe

 

, , , ,

Leave a comment

FreeSWITCH performance test on PC Engines APU

This test is analogous to the one I described for Intel Atom CPU.This time it’s the new APU board from PC Engines, the maker of famous ALIX and WRAP boards. APU is a fanless appliance board, with a dual-core 1GHz AMD G series CPU. The overall performance is comparable to that of Intel Atom.

In these tests, FreeSWITCH was forwarding the call to itself on request by pressing *1. Each such forwarding resulted in creating four new channels in G722 and G711, thus resulting in transcoding to G711 and back. For example, if “show channels” shows 5 channels, it’s equivalent to 2 simultaneous calls with transcoding.

Test result: 57 channels were running completely fine, 65 channels had slight distortions, and with 85 channels the speech was still recognizable, but with significant distortions. With Speex instead of G722, distortions were quite annoying at 25 channels. Thus, the APU platform can easily be used as a small-to-medium business PBX for  20-30 simultaneous calls if there’s not too much transcoding.

Test details follow.

Read the rest of this entry »

, , , ,

1 Comment

Call forwarding/redirection in FreeSWITCH

Consider you have two different contexts in your dialplan for inbound and outbound calls: the “public” context transfers the calls into “XXX_inbound” (XXX being your organization name), and the user directory has “XXX_outbound” as “user_context” variable.

Having two contexts, you have more flexibility in defining the short dial strings and outbound destinations.

But there’s a little problem: if the SIP client redirects the ringing call, or if the user makes an attended transfer, FreeSWITCH would initiate a new outbound leg in the same context where the call was bridged toward the SIP client.

As a solution, you need to define a new extension in your XXX_inbound context which would match PSTN outbound numbers. The channel will already have all custom variables which were set before bridging toward the SIP client, so you can set an additional condition criteria to make sure that this is the redirected call. This example would be placed at the bottom of the inbound context, and “directory_ext” is the variable that was earlier in the same context before the call was bridged to the SIP client:

    <extension name="call_forward">
      <condition field="destination_number" expression="^\d+$"/>
      <condition field="${directory_ext}" expression="^70\d$">
        <action application="set" data="hangup_after_bridge=true"/>
        <action application="set" data="continue_on_fail=false"/>
        <action application="bridge" data="${outgw}/${destination_number}"/>
      </condition>        
    </extension>

, , ,

1 Comment

Minimal FreeSWITCH configuration

It’s always a bit of an effort to remove unneeded features from the default FreeSWITCH configuration. So, I made the minimal configuration which still allows to start the server, but does completely nothing. It’s now much easier to start a new server configuration for any new project.

The configuration is placed at Github. It’s very straightforward to use with FreeSWITCH Debian packages, and can also be used if you compile it from sources:

cd /etc
git clone https://github.com/xlab1/freeswitch_conf_minimal.git freeswitch

The configuration contains a number of empty “stub.xml” files in order to make the XML pre-processor happy.

It also makes sense to start using Git for your own FreeSWITCH configurations 🙂

, , , ,

2 Comments

FreeSWITCH performance on Intel Atom CPU

There are multiple low-power, fanless  appliances on the market, and most of them are powered by Intel Atom processors. I needed an estimation how well an Atom would perform for a FreeSWITCH PBX application.

In this test, I use two Acer Aspire One notebooks with different processors:

  • atom01: Atom N2600 (2 cores, 4 virtual CPUs, 512KB cache and 600MHz per virtual CPU, 12768.02 BogoMIPS)
  • atom02: Atom N570 (2 cores, 4 virtual CPUs, 512KB cache and 1000MHz per virtual CPU, 13302.08 BogoMIPS)

Both notebooks are running 32-bit Debian 7 Wheezy (Kernel version 3.2.0-4-686-pae), and FreeSWITCH version 1.2.13 from pre-built Debian packages.

Test results summary

All calls in this test used transcoding between G.711alaw and G.722. The bottleneck in performance was always at the N2600 (atom01), because of slower CPU. In general, N570 can handle approximately 30% higher load than N2600.

With 10 concurrent calls (21 channels on atom01 and 20 channels on atom02), there is no voice distortion and new call processing does not disturb the ongoing calls. Each virtual CPU is busy at 20-25%

With 20 concurrent calls (41 channels on atom01 and 40 cannels on atom02), there is some minor voice distortion, especially during incoming calls, but quality s still acceptable.

With 27 concurrent calls (55 and 54 channels), voice distortions were too high and not acceptable. Every virtual CPU on atom01 was busy at around 50%, which means full load for the whole CPU.

With 20 concurrent calls without transcoding (PCMA only in all call legs), each CPU core on atom01 was utilized at around 9-10%. So, theoretically the platform can handle up to 40-50 simultaneous calls in non-transcoding mode.

Only the voice quality was tested. CPS was not tested, and it depends heavily on the complexity of the dialplan. But the overall response of the system was quite acceptable.

Read the rest of this entry »

, , , , , ,

1 Comment

Out-of-business greeting with FreeSWITCH

After I got my US number at Callcentric, I got several wrong calls in the following days. The calls were quite late at night, and most of them dropped after few seconds, before I could take up the handset. And another ring around 3am was really long and loud, and it dropped anyway before I could come up and pick the call.

First, I needed to record my own greeting. In “default” dialplan, I added a new extension. It takes a recording and plays it back :

  <!-- 7396: Record a greeting -->
  <extension name="app_7396">
    <condition field="destination_number" expression="^7396$">
      <action application="answer"/>
      <action application="sleep" data="500"/>
      <action application="playback" data="tone_stream://%(100,100,1400,2060,2450,2600)"/>
      <action application="set" data="playback_terminators=#"/>
      <action application="set" data="record_waste_resources=true"/>
      <action application="set" 
              data="recfilename=$${base_dir}/recordings/greeting_${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
      <action application="record" data="${recfilename}"/>
      <action application="sleep" data="700"/>
      <action application="playback" data="tone_stream://%(100,100,1400,2060,2450,2600)"/>
      <action application="playback" data="${recfilename}"/>
      <action application="hangup"/>
    </condition>
  </extension>

As I’m using a Gigaset 610IP handset with G722 codec, the produced recording had 16KHz sampling rate, and needed to be resampled, because inbound external calls are G711 only:

sox recordings/greeting_2013-08-17-11-46-35.wav sounds/dvop/8000/ssinyagin_oob.wav rate 8000

Then my extension in “public” dialplan is modified to play the greeting unless the call is between 7am and 11pm. It also plays MOH for 5 seconds before bridging the call, and continues playing MOH while ringing my phone.  This gives the mistaken caller another chance to realize that something is wrong and drop the call.

  <extension name="pub_ssinyagin">
    <condition field="destination_number" expression="^ssinyagin$" break="on-false">
      <action application="set" data="timezone=Europe/Zurich" inline="true"/> 
    </condition>

    <!-- 7:00 - 23:00 -->
    <condition minute-of-day="420-1000" break="on-true">
      <action application="answer"/>
      <action application="set" data="playback_timeout_sec=5"/>
      <action application="playback" data="$${hold_music}"/>
      <action application="set" data="ringback=$${hold_music}"/>
      <action application="transfer" data="7110 XML default"/>
    </condition>

    <condition>
      <action application="answer"/>
      <action application="sleep" data="1000"/>
      <action application="playback" data="$${sounds_dir}/dvop/ssinyagin_oob.wav"/>
      <action application="hangup"/>
    </condition>
  </extension>

, ,

Leave a comment

Free US number and Caller ID manipulation

Callcentric offers US numbers in NY area code, with zero recurring costs. This is very convenient if you want your USA customers to connect to your PBX. After ordering a free number, you create a SIP account and route the DID to it. The service allows to register multiple free numbers. Forwarding to SIP URI is not supported.

Upon receiving a call, the caller ID in From field will look like 16313335447, with the country code without any leading symbols. The following piece of FreeSWITCH configuration (in public context) alters the caller ID in order to look like a normal number in a European dial plan:

  <extension name="intl_normalize" continue="true">
    <!-- remove Swiss country code -->
    <condition field="${caller_id_number}" expression="^41(\d+)" break="on-true">
      <action application="set" data="effective_caller_id_number=0$1"/>
      <action application="set" data="effective_caller_id_name=0$1"/>
    </condition>
    <!-- add 00 in front of country code -->
    <condition field="${caller_id_number}" expression="^[1-9]" break="on-true">
      <action application="set" data="effective_caller_id_number=00${caller_id_number}"/>
      <action application="set" data="effective_caller_id_name=00${caller_id_number}"/>
    </condition>
  </extension>

It is important to set both effective_caller_id_number and effective_caller_id_name variables. If only effective_caller_id_number is set, the effective_caller_id_name still keeps the original caller ID number, and if the call is bridged to a local extension, the SIP phone may want to use it for displaying the caller.

 

 

, , ,

Leave a comment

Handling e164 numbers in FreeSWITCH

SIP clients installed on smartphones may pick up the destination number from the phone book, and it’s sometimes in e.164 format (+[countrycode][localdigits]).

The following piece of XML dialplan transforms such numbers into the standard form that is expected by most PSTN VoIP providers. This example assumes that the FreeSWITCH server is located in Switzerland and +41 is the e.164 prefix for in-land calls. It returns the call to the same context, making the switch traverse the whole context dialplan from the beginning. It makes sense to place this extension at the bottom of a context.

    <extension name="e164_pstn">
      <condition field="destination_number" expression="^\+41(\d+)" break="on-true">
        <action application="transfer" data="0$1 XML ${context}"/>
      </condition>
      <condition field="destination_number" expression="^\+(\d+)" break="on-true">
        <action application="transfer" data="00$1 XML ${context}"/>
      </condition>
    </extension>

, ,

2 Comments

FreeSWITCH: Limiting the number of concurrent calls on multiple SIP accounts

The user has several SIP accounts on a vPBX, and he wants that maximum one call is possible at a time.

The limit application in FreeSWITCH allows to control the number of concurrent calls, but one should be careful with when this limit should be applied. The switch decrements the limit counter automatically when a channel is terminated. But if the limit is executed on a-leg, and b-leg is transferred, the limit counter decreases only when the a-leg finishes the call. As a result, the user may receive a call, transfer it to a new destination and hang up, but the new calls are not coming in because the limit counter is reset when the original call ends.

In order to reset the limit counter after the b-leg is transferred, the limit application needs to be executed on b-leg only. This is possible by exporting the execute_on_answer variable with nolocal modifier.

The example also shows how to retrieve user variables from the XML directory in the calls toward the user.

Read the rest of this entry »

, , ,

2 Comments

Summary on domains and profiles in FreeSWITCH

A brief and very useful summary of FreeSWITCH’s author in the mailing list:

[Freeswitch-users] Domains and profiles
Anthony Minessale
Mon Nov 12 22:16:50 MSK 2012

Read the rest of this entry »

, ,

Leave a comment