Introduzione a FreeSWITCH
by admin on Apr.10, 2009, under Telefonia, VoIP
FreeSWITCH è una telephony application open-source, non dissimile da Asterisk, di cui però non costituisce un fork, come CallWeaver, anche se è principalmente la creatura dello sviluppatore Anthony Minessale, che pure ha contribuito allo sviluppo di Asterisk.
Le differenze architetturali sono invece notevoli, e sarebbe interessante, credo, esaminarle in un articolo specifico.
FreeSWITCH rende possibile allestire un PBX open source o interfacciarsi con altri sistemi PBX open source PBX come Bayonne, YATE o lo stesso Asterisk.
Può essere anche utilizzato per costruire un gateway multi-protocollo, in grado di unificare varie tecnologie come SIP, H.323, IAX2, LDAP, Zeroconf, XMPP / Jingle etc.
FreeSWITCH è scritto in C, totalmente ex-novo, progettato comunque per utilizzare ove possibile le molte librerie software già esistenti.
Possiede una architettura modulare, estendibile, con poche indispensabili funzionalità implementate nel core (libfreeswitch), e con moduli opzionali a fare tutto il resto.
FreeSWITCH opera su Windows, Mac OSX, Linux, *BSD, ed altri dialetti Unix ed è rilasciato sotto licenza MPL.
L’installazione può avvenire in vari modi, tramite packages binari, tramite compilazione di sorgenti da tarball o tramite compilazione di sorgenti ottenuti da svn, come in questo caso:
# cd /usr/src/
# svn checkout http://svn.freeswitch.org/svn/freeswitch/trunk
Ubuntu Intrepid 8.10 utilizza libtool 2.2.4, perciò vi è bisogno di effettuare un downgrade:
# wget http://launchpadlibrarian.net/14599325/libtool_1.5.26-4_i386.deb
# dpkg -i libtool_1.5.26-4_i386.deb
dpkg - warning: downgrading libtool from 2.2.4-0ubuntu4 to 1.5.26-4.
[...]
# cd trunk
# ./bootstrap.sh
# make
# make install
# make sounds-install
# make moh-install
Files di configurazione
I dati di configurazione relativi a FreeSWITCH sono in formato XML. Tali files sono localizzati nella directory conf, immediatamente sotto la directory di installazione di FreeSWITCH. Per default su di un sistema Unix-like dovrebbe essere /usr/local/freeswitch/conf.
# ls -F /usr/local/freeswitch/conf
autoload_configs/ extensions.conf jingle_profiles/ notify-voicemail.tpl vars.xml
dialplan/ freeswitch.xml lang/ sip_profiles/ voicemail.tpl
directory/ fur_elise.ttml mime.types tetris.ttml web-vm.tpl
vars.xml
Nella configurazione di default il file vars.xml viene usato per definire alcune variabili diffusamente utilizzate. In prima istanza si potrebbe voler modificare alcune direttive:
[...]
<X-PRE-PROCESS cmd=”set” data=”outbound_caller_name=FreeSWITCH”/>
<X-PRE-PROCESS cmd=”set” data=”outbound_caller_id=8777423583″/>
<X-PRE-PROCESS cmd=”set” data=”call_debug=false”/>
[...]
Vi è anche definita la porta di default di Freeswitch:
[...]
<X-PRE-PROCESS cmd=”set” data=”internal_sip_port=5060″/>
[...]
autoload_configs
autoload_configs è una directory dove si trovano molti dei files di configurazione di freeswitch.
Il file di configurazione di default freeswitch.xml preprocessa tali files xml.
# ls /usr/local/freeswitch/conf/autoload_configs
acl.conf.xml fax.conf.xml modules.conf.xml switch.conf.xml
alsa.conf.xml fifo.conf.xml opal.conf.xml syslog.conf.xml
cdr_csv.conf.xml iax.conf.xml perl.conf.xml timezones.conf.xml
conference.conf.xml ivr.conf.xml pocketsphinx.conf.xml unicall.conf.xml
console.conf.xml java.conf.xml portaudio.conf.xml voicemail.conf.xml
dialplan_directory.conf.xml lcr.conf.xml post_load_modules.conf.xml xml_cdr.conf.xml
dingaling.conf.xml limit.conf.xml python.conf.xml xml_curl.conf.xml
easyroute.conf.xml local_stream.conf.xml rss.conf.xml xml_rpc.conf.xml
enum.conf.xml logfile.conf.xml shout.conf.xml zeroconf.conf.xml
event_multicast.conf.xml lua.conf.xml sofia.conf.xml
event_socket.conf.xml memcache.conf.xml spidermonkey.conf.xml
modules.conf.xml
modules.conf.xml indica a freeswitch quali moduli caricare.
sofia.conf.xml
mod_sofia è usato in FreeSWITCH per creare gli endpoints sip.
Per chi ha familiarità con Asterisk, un profile in mod_sofia è simile a un channel sip.
Il file sofia.conf.xml include altri files xml per definire molteplici “profiles”. Un profilo è un SIP UA (an endpoint), che comunica con altri SIP endpoints.
SIP_Profiles
Il concetto di SIP Profile in FreeSWITCH può talvolta indurre confusione. Contrariamente ad altri softswitches (come Asterisk), FreeSWITCH vi permette di gestire i media (calls, video, etc.) in maniera differenziata in base a dove il device si trovi rispetto alla rete. Questo incrementa la sicurezza così come fornisce ulteriori funzionalità.
I profili di default sono “internal” ed “external”, servono ciascuno ad uno scopo particolare e sono localizzati in:
$PREFIX/conf/sip_profiles/PROFILE_NAME.xml — dove PROFILE_NAME è il nome del profilo.
# ls -F /usr/local/freeswitch/conf/sip_profiles/
external/ external.xml internal/ internal-ipv6.xml internal.xml
Internal
Questo profilo generalmente si riferisce a devices che risiedono sulla rete interna. Tali devices assumeranno tutte le impostazioni di configurazione settate nel profilo internal. Tipicamente, qui vanno definiti i telefoni interni con relative extensions. Per default, questi devices devono usare la autenticazione SIP.
Il profilo Internal (comunemente “default”) è configurato per accettare richieste all’indirizzo IP primario della macchina (a meno che non si imposti $${domain} a qualcosa di diverso in vars.xml) sulla porta 5060 (porta sip di default). Il profilo internal SIP autentica le chiamate e non è normalmente utilizzabile per configurare trunks a providers o terminali esterni.
Il profilo Internal dovrebbe venire usato qualora si intenda gestire la registrazione dei sip clients (come un SIP registrar).
Il dialplan per tale profilo (per-default) è definito nel context default
External
Questo profilo generalmente si riferisce a devices o gateways che risiedono all’esterno della rete locale. Generalmente qui è dove vanno definiti i trunks verso VoIP carriers etc. Tali devices saranno interessati dalle opzioni di configurazione presenti nel profilo external.
Il profilo External (comunemente “di outbound”) gestisce le registrazioni ad un eventuale SIP provider. Il SIP provider invierà e riceverà chiamate in base al profilo external. Il profilo external permette la chiamata anonima, richiesta dal momento che il nostro provider non si autenticherà mai presso di noi per inviarci una chiamata.
Per rendere FreeSwitch sicuro è opportuno collegare il profilo di outbound ad un context del dialplan differente da ‘default’, che, nella configurazione di default appunto, è dove vengono proiettati gli utenti autenticati.
NOTA: La porta di default per le connessioni esterne è la 5080.
Il dialplan per questo profilo (per default) si trova definito nel context public
dialplan
Il dialplan di FreeSWITCH è un completo meccanismo di call-routing basato su XML. (Esiste pure il supporto per dialplans Asterisk-like dialplans così come per altri tipi di dialplan database-driven)
E’ raccomandabile compilare FreeSWITCH con la configurazione di default ed assicurarsi che operi prima di iniziare a fare customizzazioni.
E’ pure raccomandabile mettere il proprio diaplan custom nella extensions subdirectory sotto conf/dialplan. Si possono creare uno o più files XML in questa subdirectory, che verranno inclusi nel dialplan grazie ad una direttiva “include” nel file default.xml. Mantenendo le extensions custom separate da default.xml sarà possibile aggiornare default.xml senza doverle reintrodurre.
directory
La directory “directory” contiene le credenziali di autenticazione per gli altri endpoints sip che si registrano con freeswitch (comunemente gli utenti interni). Per default freeswitch è configurato per processare la variabile globale $PREFIX/conf/directory/default/*.xml dalla configurazione presente in freeswitch.xml $PREFIX/conf/directory/*.xml, e questo potrebbe indurre una certa confusione.
# ls -F /usr/local/freeswitch/conf/directory
default/ default.xml
# ls /usr/local/freeswitch/conf/directory/default
1000.xml 1003.xml 1006.xml 1009.xml 1012.xml 1015.xml 1018.xml default.xml
1001.xml 1004.xml 1007.xml 1010.xml 1013.xml 1016.xml 1019.xml example.com.xml
1002.xml 1005.xml 1008.xml 1011.xml 1014.xml 1017.xml brian.xml
L’avvio di FreeSWITCH su sistemi Unix-like avviene da linea di comando.
Altri argomenti opzionali da passare a freeswitch sono:
-help — this message
-nf — no forking
-hp — enable high priority settings
-stop — stop freeswitch
-nc — do not output to a console and background
-conf [confdir] — specify an alternate config dir
-log [logdir] — specify an alternate log dir
-db [dbdir] — specify an alternate db dir
# cd /usr/local/freeswitch/bin
# ./freeswitch
Error: stacksize 240 is too large: run ulimit -s 240 or run bin/freeswitch -waste.
auto-adjusting stack size for optimal performance….
2009-04-10 02:13:52 [INFO] switch_core_sqldb.c:494 switch_core_sqldb_start() Opening DB
[...]
2009-04-10 02:13:57 [CONSOLE] switch_core.c:1322 switch_core_init_and_modload()
FreeSWITCH Version 1.0.trunk (12970M) Started.
Crash Protection [Disabled]
Max Sessions[1000]
Session Rate[30]
SQL [Enabled]
freeswitch@silversurfer>
Il prompt di FreeSWITCH™ diviene disponibile una volta lanciata l’applicazione.
freeswitch@silversurfer> help
API CALL [help()] output:
Valid Commands:
acl,<ip> <list_name>,compare an ip to an acl list,mod_commands
alias,add <alias> <command> | del [<alias>|*],Alias,mod_commands
[...]
xml_locate,[root | <section> <tag> <tag_attr_name> <tag_attr_val>],find some xml,mod_commands
xml_wrap,<command> <args>,Wrap another api command in xml,mod_commands
freeswitch@silversurfer> show application sound_test
API CALL [show(application sound_test)] output:
name,description,syntax,key
sound_test,Analyze Audio,,mod_dptools
1 total.
Testare immediatamente il funzionamento di FreeSwitch sfruttando le impostazioni di default è facilissimo.
Si può ad esempio impostare un telefono SIP (o anche un softphone) con username 1000, stesso authentication username, con password 1234 e registrar uguale all’indirizzo IP del server per essere immediatamente registrati e poter accedere ad alcune extension di test preconfigurate:
* 1000, 1001, …, 1019 - Generiche SIP extensions
* 5000 - demo IVR
* 9995 - echo test con 5 secodi di ritardo
* 9996 - standard echo test
* 9999 - music on hold
Quanto segue è il riscontro, in console, di una chiamata all’interno 5000, e quindi della scelta (3) di testare la musica di attesa.
freeswitch@silversurfer> 2009-04-10 11:48:44 [NOTICE] switch_channel.c:597 switch_channel_set_name() New Channel sofia/internal/1000@192.168.1.10 [c7f36584-25b4-11de-a98f-836bd659bc58]
2009-04-10 11:48:44 [INFO] mod_dialplan_xml.c:252 dialplan_hunt() Processing 1000->5000 in context default
2009-04-10 11:48:44 [NOTICE] mod_dptools.c:649 answer_function() Channel [sofia/internal/1000@192.168.1.10] has been answered
2009-04-10 11:49:18 [NOTICE] switch_ivr.c:1345 switch_ivr_session_transfer() Transfer sofia/internal/1000@192.168.1.10 to XML[9999@default]
2009-04-10 11:49:18 [INFO] mod_dialplan_xml.c:252 dialplan_hunt() Processing 1000->9999 in context default
2009-04-10 11:50:18 [NOTICE] sofia.c:3442 sofia_handle_sip_i_state() Hangup sofia/internal/1000@192.168.1.10 [CS_EXECUTE] [NORMAL_CLEARING]
2009-04-10 11:50:18 [NOTICE] switch_core_session.c:1019 switch_core_session_thread() Session 7 (sofia/internal/1000@192.168.1.10) Ended
2009-04-10 11:50:18 [NOTICE] switch_core_session.c:1021 switch_core_session_thread() Close Channel sofia/internal/1000@192.168.1.10 [CS_DONE]
Non è difficile nemmeno testare l’integrazione con un sip provider tipo voipcheap, che utilizzo spesso nei test Asterisk.
A questo proposito ho impostato la seguente sezione nel file /usr/local/freeswitch/conf/dialplan/default.xml:
<extension name=”Long Distance - voipcheap”>
<condition field=”destination_number” expression=”^(0039d{10})$”>
<action application=”set” data=”effective_caller_id_number=12223334444″/>
<action application=”bridge” data=”sofia/gateway/voipcheap/$1″/>
</condition>
</extension>
e poi creato un file di nome voipcheap.xml in /usr/local/freeswitch/conf/sip_profiles/external:
<include>
<gateway name=”voipcheap”>
<param name=”username” value=”xxxxxx”/>
<param name=”realm” value=”sip.voipcheap.com”/>
<param name=”password” value=”xxxxxx”/>
<param name=”register” value=”false”/>
</gateway>–>
</include>
Una volta rese operative tali modifiche tramite il comando reloadxml, ho potuto chiamare una normale utenza telefonica dall’interno utilizzato in precedenza, come indica il seguente output:
silversurfer> 2009-04-10 15:41:57 [NOTICE] switch_channel.c:597 switch_channel_set_name() New Channel sofia/internal/1000@192.168.1.10 [5c4de0cc-25d5-11de-958b-a550ef483cb1]
2009-04-10 15:41:57 [INFO] mod_dialplan_xml.c:252 dialplan_hunt() Processing 1000->00390437xxxxxx in context default
2009-04-10 15:41:57 [NOTICE] switch_channel.c:597 switch_channel_set_name() New Channel sofia/external/00390437xxxxxx [5c5863f8-25d5-11de-958b-a550ef483cb1]
2009-04-10 15:41:58 [NOTICE] sofia_glue.c:2552 sofia_glue_tech_media() Pre-Answer sofia/external/00390437xxxxxx!
2009-04-10 15:41:58 [INFO] mod_sofia.c:1336 sofia_receive_message() Asked to send early media by sofia/internal/1000@192.168.1.10
2009-04-10 15:41:58 [INFO] mod_sofia.c:1379 sofia_receive_message() Ring SDP:
v=0
o=FreeSWITCH 1239347048 1239347049 IN IP4 192.168.1.10
s=FreeSWITCH
c=IN IP4 192.168.1.10
t=0 0
m=audio 23870 RTP/AVP 8 101
a=rtpmap:8 pcma/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=silenceSupp:off - - - -
a=ptime:20
a=sendrecv
2009-04-10 15:41:58 [NOTICE] mod_sofia.c:1382 sofia_receive_message() Pre-Answer sofia/internal/1000@192.168.1.10!
2009-04-10 15:42:07 [NOTICE] sofia.c:3332 sofia_handle_sip_i_state() Channel [sofia/external/00390437xxxxxx] has been answered
2009-04-10 15:42:07 [NOTICE] switch_ivr_bridge.c:306 audio_bridge_thread() Channel [sofia/internal/1000@192.168.1.10] has been answered

