Friday, October 24, 2008

Cisco Callmanager Express, XML Services

I've played a little bit with the integration of XML Services to the CME. The service is hosted on a Linux system with Apache as a web server.
 Works quite well ...

The necessary CME config:

telephony-service
url services http://172.20.29.88/html/ciscoxml/menu.php


My menu.php:

root@home-nas:/usr/lib/cgi-bin# cat /var/www/html/ciscoxml/menu.php
<ciscoipphonemenu>
 <title>My XML Services</title>
 <prompt>Please make your selection.</prompt>
 <menuitem>
   <name>Telefonbuch</name>
   <url>http://172.20.29.88/html/ciscoxml/Phonebook.php</url>
 </menuitem>
 <menuitem>
   <name>RSS_Feed</name>
   <url>http://172.20.29.88/cgi-bin/rss2cisco.pl</url>
 </menuitem>
 <menuitem>
   <name>Weather, News and Stocks</name>
   <url>http://phone-xml.berbee.com/menu.xml?opts=13456</url>
 </menuitem>
</ciscoipphonemenu>
root@home-nas:/usr/lib/cgi-bin#


My Phonebook.php:

root@home-nas:/usr/lib/cgi-bin# cat /var/www/html/ciscoxml/Phonebook.php
<ciscoipphonedirectory>
 <title>XML Directory</title>
 <prompt>Please Choose:</prompt>
 <directoryentry>
   <name>pepe, schnitzel</name>
   <telephone>01234</telephone>
 </directoryentry>
 <directoryentry>
   <name>pepe, schnatzel</name>
   <telephone>3453456346</telephone>
 </directoryentry>
 <directoryentry>
   <name>pepe, schnetzel</name>
   <telephone>234523</telephone>
 </directoryentry>
</ciscoipphonedirectory>
root@home-nas:/usr/lib/cgi-bin#

My rss2cisco.pl:
You get the original one from http://dontpokebadgers.com/rss2cisco/.
Thank you Joshua!!

root@home-nas:/usr/lib/cgi-bin# cat rss2cisco.pl
#!/usr/bin/perl
use strict;
#use warnings;
use CGI;
use LWP::Simple qw($ua get);
use XML::RSS;
use Cisco::IPPhone;
use vars qw($pathto @descriptions @feeds);
($#descriptions,$#feeds) = (-1,-1);
# RSS2cisco, An RSS feed to Cisco IP Phone Script version 2.0
# Copyright 2007, Joshua Cantara
# This program is licensed under the GPL: http://www.gnu.org/licenses/gpl.txt
# Newest version can always be found at: http://dontpokebadgers.com/rss2cisco/
# ************************************************************
# ATTENTION: EDIT THE FOLLOWING VARIABLES!!
# ************************************************************
# Change the following to the folder location of rss2cisco.pl on your server
# --------> DO NOT ADD A TRAILING SLASH. <--------
$pathto = 'http://172.20.23.88/cgi-bin';
# Add/Remove RSS feeds below. An example is provided.
# --------> REMOVE "http://" <--------
push(@descriptions,'Wetter');
push(@feeds,'wetter.com/wetter_rss/wetter.xml');
push(@descriptions,'BBC World News');
push(@feeds,'newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml');
push(@descriptions,'Cisco Press Promos');
push(@feeds,'www.ciscopress.com/promotions/promotion_rss.asp');
push(@descriptions,'Cisco News');
push(@feeds,'www.channelinsider.com/rss-feeds-1.xml');
push(@descriptions,'Queenstown weather');
push(@feeds,'www.rssweather.com/wx/za//queenstown/rss.php');
# --------> There is a CISCO IMPOSED MAXIMUM of 64 feeds. <--------
# ************************************************************
# ATTENTION: DON'T CHANGE ANYTHING BELOW THIS LINE!
# ************************************************************
my $query = new CGI;  if ($query->param('rssurl') eq '') { &printmenu; }
elsif ($query->param('rssurl') ne '') { &printfeed; }
else { &error; }
exit;
################################################
# PRINT A MENU OF FEEDS
################################################
sub printmenu {
my $xmlmenu = new Cisco::IPPhone;
$xmlmenu->Menu( { Title => "Your RSS Feeds", Prompt => "Choose a Feed", Text => "" });
my $i = 0;
foreach my $item (@descriptions)
 {
 $item = encode_entities($item);
 my $url = "$pathto/rss2cisco.pl?rssurl=$i";
 $url = encode_entities($url);
 $xmlmenu->AddMenuItem({ Name => $item, URL => $url});
 $i++;
 }
print $xmlmenu->Content;
}
################################################
# PRINT A SINGLE RSS FEED
################################################
sub printfeed {
# Get and parse RSS feed
my $query = new CGI;
my $feednum = $query->param('rssurl');
my $rss = new XML::RSS();
my $rssfeed = 'http://' . $feeds[$feednum];
$ua->timeout(15);
my $raw = get($rssfeed);
$rss->parse($raw);
# Read RSS news items and convert
my $body = "";
foreach my $item (@{$rss->{'items'}})
 {
 my $itemtitle = encode_entities($item->{'title'});
 my $itemdescription = $item->{'description'};
 $itemdescription = encode_entities($itemdescription);
 $body .= $itemtitle . "\n------------------------------\n" . $itemdescription . "\n\n";
 }
if (length($body) > 3600)
 {
 $body = substr($body,0,3600);
 $body .= qq|\n------------------------------\n|;
 $body .= qq|Sorry, this feed has exceeded the maximum display size and has been truncated.|;
 }
# Prepare and return final Cisco XML document
my $xmloutput = new Cisco::IPPhone;
my $title = encode_entities($descriptions[$feednum]);
$xmloutput->Text({ Title => $title, Prompt => "Viewing Feed...", Text => $body });
print $xmloutput->Content;
}
###############################################################
# PRINT ERROR MESSAGE
###############################################################
sub error {
my $xmloutput = new Cisco::IPPhone;
$xmloutput->Text({ Title => "Error", Prompt => "Please Go Back", Text => "Sorry, an error has occured." });
print $xmloutput->Content;
}
###############################################################
# ENCODE/DECODE ENTITIES
###############################################################
sub encode_entities {
my $text = shift (@_);
$text =~ s/<(.|\n)+?>//g;
$text =~ s/’/'/g;
$text =~ s/&amp;/&amp;/g;
$text =~ s/<!--</g; $text =~ s/-->/&gt;/g;
return $text;
}
root@home-nas:/usr/lib/cgi-bin#

To get this to work you should follow the instruction on the homepage of the script (http://dontpokebadgers.com/rss2cisco/).
Additionaly, to get the installation of XML::RSS working, I had to install expat-2.0.1. Download the XML parser expat at
http://sourceforge.net/projects/expat/.

Saturday, May 10, 2008

Sendmail for GMX communication

I configured the system to send the emails with the WAV attachments to an GMX email address.
Thats my sendmail.mc:

root@home-nas:~# cat /etc/mail/sendmail.mc
include(`/usr/share/sendmail/cf/m4/cf.m4')dnl
VERSIONID(`setup debian Linux')dnl
OSTYPE(`linux')dnl
dnl# DOMAIN(`debian-mta')dnl
dnl#
define(`confPRIVACY_FLAGS', `authwarnings,novrfy,noexpn,restrictqrun')dnl
define(`SMART_HOST',`mail.gmx.net')dnl
define(`confTO_IDENT', `0')dnl
define(`confCW_FILE', `-o /etc/mail/local-host-names')dnl
define(`confBIND_OPTS', `WorkAroundBrokenAAAA')dnl
define(`confNO_RCPT_ACTION', `add-to-undisclosed')dnl
define(`confPRIVACY_FLAGS', `authwarnings,noexpn,novrfy')dnl
define(`confLOG_LEVEL',15)dnl
FEATURE(`genericstable')dnl
FEATURE(`generics_entire_domain')dnl
FEATURE(`relay_hosts_only')dnl
FEATURE(`authinfo',`hash -o /etc/mail/auth/client-info')dnl
FEATURE(`use_cw_file')dnl
FEATURE(`access_db', `hash -T /etc/mail/access')dnl
FEATURE(`local_procmail',`',`procmail -t -Y -a $h -d $u')dnl
FEATURE(`redirect')dnl
FEATURE(`masquerade_entire_domain')dnl
FEATURE(`masquerade_envelope')dnl
FEATURE(`allmasquerade')dnl
FEATURE(`always_add_domain',`gmx.net')dnl
EXPOSED_USER(`root')dnl
GENERICS_DOMAIN(`home-nas.lab.test')dnl
MASQUERADE_AS(`asterisk1.local')dnl
MASQUERADE_DOMAIN(`lab.test')dnl
LOCAL_DOMAIN(`localhost.localdomain')dnl
MAILER(local)dnl
MAILER(smtp)dnl
MAILER(procmail)dnl
root@home-nas:~#


My submit.mc:

root@home-nas:~# cat /etc/mail/submit.mc
divert(-1)dnl
#-----------------------------------------------------------------------------
# $Sendmail: submit.mc,v 8.13.8 2006-09-30 07:18:48 cowboy Exp $
#
# Copyright (c) 2000-2005 Richard Nelson. All Rights Reserved.
#
# cf/debian/submit.mc. Generated from submit.mc.in by configure.
#
# submit.mc prototype config file for building Sendmail 8.13.8
#
# Note: the .in file supports 8.7.6 - 9.0.0, but the generated
# file is customized to the version noted above.
#
# This file is used to configure Sendmail for use with Debian systems.
#
# If you modify this file, you will have to regenerate /etc/mail/submit.cf
# by running this file through the m4 preprocessor via one of the following:
# * `sendmailconfig`
# * `make`
# * `m4 /etc/mail/submit.mc > /etc/mail/submit.cf`
# The first two options are preferred as they will also update other files
# that depend upon the contents of this file.
#
# The best documentation for this .mc file is:
# /usr/share/doc/sendmail-doc/cf.README.gz
#
#-----------------------------------------------------------------------------
divert(0)dnl
#
# Copyright (c) 2000-2002 Richard Nelson. All Rights Reserved.
#
# This file is used to configure Sendmail for use with Debian systems.
#
define(`_USE_ETC_MAIL_')dnl
include(`/usr/share/sendmail/cf/m4/cf.m4')dnl
VERSIONID(`$Id: submit.mc, v 8.13.8-2 2006-09-30 07:18:48 cowboy Exp $')
OSTYPE(`debian')dnl
DOMAIN(`debian-msp')dnl
dnl #
dnl #---------------------------------------------------------------------
dnl # Masquerading information, if needed, should go here
dnl # You likely will not need this, as the MTA will do it
dnl #---------------------------------------------------------------------
dnl MASQUERADE_AS()dnl
dnl FEATURE(`masquerade_envelope')dnl
dnl #
dnl #---------------------------------------------------------------------
dnl # The real reason we're here: the FEATURE(msp)
dnl #---------------------------------------------------------------------
FEATURE(`msp', `[127.0.0.1]', `MSA')dnl
dnl #
dnl #---------------------------------------------------------------------
dnl # Some minor cleanup from FEATURE(msp)
dnl #---------------------------------------------------------------------
dnl #
dnl #---------------------------------------------------------------------
root@home-nas:~#


My client-info:

root@home-nas:~# cat /etc/mail/auth/client-info
Authinfo:mail.gmx.net "U:yaya@gmx.net" "I:yaya@gmx.net" "P:xxx" "R:gmx.net" "M:CRAM-MD5"
root@home-nas:~#


My access:

root@home-nas:~# cat /etc/mail/access
localhost.localdomain RELAY
localhost RELAY
127.0.0.1 RELAY
home-nas.lab.test RELAY

root@home-nas:~#


As mentioned before, I don't claim this to be an optimized configuration, but it works. Comments welcome.

Wednesday, April 23, 2008

Asterisk & Cisco Callmanager Express (CME)

I decided to add some voicemail functionality to the lab. The Open Source Project Asterisk came to my mind. The goal was to get the voicemail forwarded, with an audio file, to a public email account at GMX. I also wanted to use the MWI function of the SCCP phones. And surprisingly, after "a little bit" of testing it worked. Remember, this is only a proof of concept, I don't claim that to be the perfect solution. Suggestions welcome.

With help from:http://www.voip-info.org/wiki/view/Asterisk+Cisco+CallManager+Express+Integration
Here is my extensions.conf:


root@home-nas:~# cat /etc/asterisk/extensions.conf
[general]

[cme]
exten => 105,1,VoiceMailMain(),p
exten => 106,1,NoOp,${CALLERID(num)}
exten => 106,2,NoOp,${CALLERID(rdnis)}
exten => 106,3,Playback(silence/1)
exten => 106,4,Voicemail(${CALLERID(rdnis)},b)
exten => 106,5,Hangup
exten => 106,106,Hangup

;Transfer on busy.
;see notes above, just sets the b flag for the voicemail application to stat the call was busy (as apposed to unavailable).
exten => 107,1,NoOp,${CALLERID(num)}
exten => 107,2,NoOp,${CALLERID(rdnis)}
exten => 107,3,Playback(silence/1)
exten => 107,4,Voicemail(${CALLERID(rdnis)},u)
exten => 107,5,Hangup
exten => 107,106,Hangup

[vm]

;CCME Specific VM
;Voice mail Key on 79xx - need to use the last 3 digits of the CallerID. See notes on "calling-number local secondary" in the telephony-service section
;of the cisco config
;exten => 105,1,NoOp,${CALLERID(num)}
;exten => 105,2,Background(silence/1)
;exten => 105,3,VoicemailMain(${CALLERID(num)}@default)
;exten => 105,4,Hangup
;exten => 105,104,Hangup
exten => 105,1,VoiceMailMain(${CALLERID(num)})

;Transfer on unavailable.
; I playback 1 second of silence to allow the call to establish correctly else the start of the audio gets cut off, if you have silence suppression or something
; I guess you could play a beep.
; Because the call is being transfered the variable ${CALLERIDNUM} contains the number of the calling device not the divice they were calling
; This would mean you would end up in your own or a non existant mailbox, the variable ${RDNIS} contains the number
; the call was redirected from and therefore can be used to specify the correct mailbox number.
exten => 106,1,NoOp,${CALLERID(num)}
exten => 106,2,NoOp,${CALLERID(rdnis)}
exten => 106,3,Playback(silence/1)
exten => 106,4,Voicemail(${CALLERID(rdnis)},b)
exten => 106,5,Hangup
exten => 106,106,Hangup

;Transfer on busy.
;see notes above, just sets the b flag for the voicemail application to stat the call was busy (as apposed to unavailable).
exten => 107,1,NoOp,${CALLERID(num)}
exten => 107,2,NoOp,${CALLERID(rdnis)}
exten => 107,3,Playback(silence/1)
exten => 107,4,Voicemail(${CALLERID(rdnis)},u)
exten => 107,5,Hangup
exten => 107,106,Hangup

root@home-nas:~#

My sip.conf:

root@home-nas:~# cat /etc/asterisk/sip.conf
[general]
insecure=port,invite
bindport=5060 ; Port to bind to (SIP is 5060)
bindaddr=0.0.0.0 ; Address to bind to (all addresses on machine)
disallow=all
allow=alaw
context=cme
host=172.20.29.90
type=peer
;callerid=Unknown

[10]
insecure=port,invite
context=vm
type=friend
qualify=yes
mailbox=10
host=172.20.29.90
;ipaddr=172.20.29.90
dtmfmode=auto
dial=SIP/10
canreinvite=no
callerid=device <10>
subscribemwi=no
nat=no
fromuser=105
vmexten=105
username=10

[53]
insecure=port,invite
context=vm
type=friend
qualify=yes
mailbox=53
host=172.20.29.90
;ipaddr=172.20.29.90
dtmfmode=auto
dial=SIP/53
canreinvite=no
callerid=device <53>
subscribemwi=no
nat=no
fromuser=105
vmexten=105
username=53

root@home-nas:~#

I forwad the emails to a public mail service from GMX.
My voicemail.conf:

root@home-nas:~# cat /etc/asterisk/voicemail.conf
[general]
emailbody=${VM_NAME},\n\New message in mailbox!! ${VM_MAILBOX}\n\n\tVon:\t${VM_CALLERID}\n\tLaenge:\t${VM_DUR} Sekunden\n\tDate:\t${VM_DATE}\n\Dial 105 to access your voicemail.\n\You can also listen at http://172.20.29.88/html/recordings/index.php , to your messages.\n\nAsterisk Rulez!!\n
serveremail=yaya@gmx.net ; Who the e-mail notification should appear to come from
fromstring=Voicemail System
nextaftercmd=yes
externnotify=chmod -R a+rw /var/spool/asterisk/voicemail/default/
[default]
10 => 1234,AJ10 Mailbox,aj10@gmx.de,,attach=yes|saycid=yes|envelope=yes|delete=no
53 => 1234,Andre Mailbox,andre@gmx.de,,attach=yes|saycid=no|envelope=yes|delete=no


root@home-nas:~#


Wednesday, April 16, 2008

Nokia Phones & Cisco Callmanager Express (CME)

After reading that Nokia phones come with a SIP client, I was curios about testing them with a Cisco Callmanager Express (CME). I have to say it works quite well. I have tested this with Nokia E60, E61, E70 & N95-8GB. MWI doesn't work with the Nokias. This is kind of a braindump of the configuration. I assume that you have a working wireless connection to your LAN. Furthermore I added a Link to a PSTN and to a SIP provider. When I add a 9 as a prefix to the phone number the system will do a dialout to the PSTN, when I dial the number without a special prefix, it will use the SIP Provider. Irrelevant parts of the configuration are partly not shown here. I really recommend the IOS ipvoicek9-mz.124-15.T3.bin for this setup. Comments welcome!!


LAB Configuration:



Phone Configuration:

SIP settings
- New SIP profile -> Use default profile
-- Profile name -> Lab
-- Service profile -> IETF
-- Default access point -> Lab
-- Public user name -> sip:10@172.20.29.90
-- Use compression -> No
-- Registration -> Always on
-- Use security -> No
-- Proxy server
--- Proxy server address -> sip:172.20.29.90
--- Realm -> None
--- Proxy server address -> sip:172.20.29.90
--- User name -> 10@172.20.29.90
--- Password -> xxx
--- Allow loose routing -> yes
--- Transport type -> UDP
--- Port -> 5060
-- Registrar server
--- Registrar server address -> sip:172.20.29.90
--- Realm -> None
--- User name -> 10@172.20.29.90
- --Password -> xxx
--- Allow loose routing -> yes
--- Transport type -> UDP
--- Port -> 5060

Internet tel.
- New profile
-- Name -> Lab
-- SIP profiles -> Lab




CME Configuration:

=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2008.04.22 19:39:16 =~=~=~=~=~=~=~=~=~=~=~=

test_gw#sh run
Building configuration...

Current configuration : 19750 bytes
!
! Last configuration change at 20:42:08 MESZ Tue Apr 1 2008 by andre
! NVRAM config last updated at 21:20:42 MESZ Wed Apr 2 2008
!
version 12.4
!
hostname test_gw
!
aaa new-model
!
!
aaa accounting connection H.323 start-stop group radius
!
!
aaa session-id common
memory-size iomem 25
!
voice-card 0
codec complexity medium
!
voice-card 2
codec complexity medium
!
ip dhcp excluded-address 172.20.29.80
172.20.29.254
!
ip dhcp pool home
network 172.20.29.0 255.255.255.0
next-server 172.20.29.15
default-router 172.20.29.90
dns-server 172.20.29.88
domain-name lab.test
option 150 ip 172.20.29.90
option 66 ip 172.20.29.90
option 128 ip 172.20.29.90
!

!
!
no voice call carrier capacity active
!
voice service pots
!
voice service voip
allow-connections h323 to h323
allow-connections h323 to sip
allow-connections sip to h323
allow-connections sip to sip
redirect ip2ip
sip
bind control source-interface FastEthernet0/0
bind media source-interface FastEthernet0/0
registrar server
no call service stop
!
!
!General SIP Configuration
voice register global
mode cme
source-address 172.20.29.90 port 5060
max-dn 12
max-pool 12
timezone 21
time-format 24
date-format D/M/Y
call-forward system redirecting-expanded
create profile sync 0834091551485351
!Configuration for Nokia N95
voice register dn 2
number 10
allow watch
name nn95
no-reg
label NN95
mwi
!
voice register pool 2
id mac 1111.2222.3333
number 1 dn 2
dtmf-relay rtp-nte
username nn95 password cisco
codec g711alaw
!
!
!
voice translation-rule 9
rule 1 /^9/ //
!
voice translation-rule 40
rule 1 /444582$/ /53/
rule 3 /444631$/ /11/
!
voice translation-rule 41
rule 1 /^53$/ /444582/
rule 3 /^11$/ /444631/
!
voice translation-rule 53
rule 3 /^\(..\)$/ /4922012345\1/
rule 5 /^492201234553$/ /53/

!
!
voice translation-profile SIP-in
translate called 53
!
voice translation-profile SIP-out
translate calling 53
!
voice translation-profile PSTN-in
translate called 40
!
voice translation-profile PSTN-out
translate calling 41
translate called 9
!
!
ip tcp path-mtu-discovery
ip ftp username ciscoftp
ip ftp password xxx
!
!
class-map match-any AutoQoS-VoIP-RTP-Trust
match ip dscp ef
class-map match-any AutoQoS-VoIP-Control-Trust
match ip dscp cs3
match ip dscp af31
!
!
policy-map AutoQoS-Policy-Trust
class AutoQoS-VoIP-RTP-Trust
priority percent 70
class AutoQoS-VoIP-Control-Trust
bandwidth percent 5
class class-default
fair-queue
!
!
gw-accounting syslog
!
!
!
!
interface FastEthernet0/0
ip address 10.99.1.1 255.255.255.0 secondary
ip address 172.20.29.90 255.255.255.0
ip accounting output-packets
ip nbar protocol-discovery
speed auto
ntp broadcast
no cdp log mismatch duplex
service-policy output AutoQoS-Policy-Trust
!
ip route 0.0.0.0 0.0.0.0 172.20.29.81
!
voice-port 0/0
!
voice-port 0/1
!
!
dial-peer voice 10 voip
translation-profile incoming SIP-in
translation-profile outgoing SIP-out
service session
destination-pattern 0.T
session protocol sipv2
session target dns:sip.Provider.SIP
incoming called-number 4922012345..
dtmf-relay rtp-nte
codec g711alaw
no vad
!
!
dial-peer voice 50 voip
translation-profile incoming PSTN-in
translation-profile outgoing PSTN-out
destination-pattern 9T
redirect ip2ip
session target ipv4:172.20.29.89
incoming called-number 444[56][839][214]
codec g711alaw
no vad
!If you register SIP phones or SCCP phones, this will give you presence information in the telephony directory
presence
presence call-list
watcher all
allow subscribe
!
!
dial-peer voice 100 voip
destination-pattern ^10[567]$
rtp payload-type nte 98
session protocol sipv2
session target ipv4:172.20.29.88
dtmf-relay rtp-nte
codec g711alaw
no vad
!
gateway
timer receive-rtp 1200
!
sip-ua
authentication username 492201234553 password xxx realm Provider.SIP
registrar dns:sip.Provider.SIP:5060 expires 5000
sip-server dns:sip.Provider.SIP
presence enable
!
!
telephony-service
no auto-reg-ephone
load 7960-7940 P00308000400
load ATA ATA030100SCCP040211A.zup
load 7970 SCCP70.8-2-2SR1S
max-ephones 16
max-dn 150
ip source-address 172.20.29.90 port 2000
auto assign 1 to 24
timeouts interdigit 5
time-zone 23
time-format 24
date-format dd-mm-yy
max-conferences 4 gain -6
moh en_bacd_music_on_hold.au
web admin system name webadmin secret xxx
dn-webedit
transfer-system full-blind
secondary-dialtone 0
directory last-name-first
directory entry 1 1234# name Test1
create cnf-files version-stamp 7960 Apr 01 2008 20:13:39
!
!
ephone-dn 1 dual-line
number 53 secondary 492201234553 no-reg primary
pickup-group 5
label 53
description Andre Janssen
name Andre Janssen
allow watch
huntstop channel
no huntstop
mwi sip
!
!
!
!
ephone 1
mac-address 1212.2323.3434
username "andre" password xxx
type 7970
button 1:1
pin 12345
!
!
!
line con 0
password xxx
line aux 0
transport preferred telnet
flowcontrol hardware
line vty 0 4
exec-timeout 180 0
password xxx
!
ntp master 3
ntp server 192.53.103.103
end

test_gw#