Planet Collab

🔒
❌ About FreshRSS
There are new available articles, click to refresh the page.
Before yesterdayangryciscoguy

Build a Chat Bot with the Cisco Spark API

By Nicholas Marus

This tutorial will get you started with a simple Cisco Spark Bot written in Node JS and hosted on Cloud9.

Making Bots Spark
https://github.com/nmarus/flint
4 forks.
0 open issues.
Recent commits:

Introduction

Getting Your Spark Access Token

First you will need your Cisco Spark API Access Token. You can use your own account or create a new “bot” account. However, if you use your own account, you will need someone else to test the commands as the application is designed to ignore commands that come from itself.

  1. Login to http://developer.ciscospark.com

  2. Click your avatar image and copy the characters listed in “My Access Token”. You will need this later when setting up Flint.

    Cicso spark token

Cloud9 Setup

Cloud9 is an online Integrated Development Environment (IDE). This allows you to build this Node JS app without having to install anything on your computer or worry about having to pinhole your firewall to allow the Spark API web-hook callbacks to access locally running application.

  1. Sign up for a free account on cloud9. This is where the code for the bot will run.

  2. After creating an account and logging into Cloud9, you will need to create a new workspace. When doing so, you will be presented with a dialog box. Choose all the defaults and define the following:

  • Workspace Name – For this tutorial we are using “mybot”, but it can be anything.
  • Description – This can be anything.
  • Template – Choose “Node.js”.

    Cloud 9 new project

    Note: If setting up a private workspace, you will need to adjust the Cloud9 workspace security settings in order for the webhooks from the Cisco Spark API to reach the webserver that runs in this app. The directions for doing this are here.

  1. Press “Create Workspace” and wait for the Cloud9 IDE to load.

  2. After the IDE has loaded, you will see that Cloud9 has set us up with a sample project. We don’t need any of this, so start by deleting the 2 existing folders in the project tree. This can be done by right clicking on the folder and selecting delete. These are named:

  • client
  • node_modules

    Cloud 9 remove template

  1. Next, edit the package.json file in your project tree. Edit the following:
  • name
  • description
  • author
  • dependencies

    The file should look something like the following. Be sure to save after you have made the changes.

    {
      "name": "mybot",
      "version": "0.0.0",
      "description": "A Cisco Spark bot using Flint",
      "main": "server.js",
      "repository": "",
      "author": "Nicholas Marus <nmarus@gmail.com>",
      "dependencies": {
      }
    }
    

    Cloud 9 package.json

Flint Application Setup
  1. Open up server.js and replace the existing code with the following. Be sure to save after you have made the changes.
  • hookUrl: The cloud9 url for your app is http://<appname>-<username>.c9users.io
  • sparkEmail: Enter the Cisco Spark Email used at the start of this tutorial.
  • sparkToken: Enter the Cisco Spark Access Token that you recorded earlier.

    var Flint = require('node-flint');
    
    // define flint setup
    var config = {
      // url to access this app's webservice
      hookUrl: 'http://<app>-<username>.c9users.io',
      // port that local server listens on
      localPort: process.env.PORT,
      // spark account email
      sparkEmail: '<spark email>',
      // spark api token
      sparkToken: '<spark access token>'
    };
    
    // init flint framework
    var flint = new Flint(config);
    
    // echo test
    flint.hears('/echo', function(bot, trigger) {
      bot.say(trigger.args.join(' '));
    });
    
    // add a person or people to room by email
    flint.hears('/add', function(bot, trigger) {
      var email = trigger.args;
      if(email) bot.add(email);
    });
    
    // remove a person or people from room by email
    flint.hears('/remove', function(bot, trigger) {
      var email = trigger.args;
      if(email) bot.remove(email);
    });
    
    // anytime someone says beer
    flint.hears(/(^| )beer( |.|$)/i, function(bot, trigger) {
      bot.say('Enjoy a beer, %s!', trigger.person.displayName);
    });
    

    Cloud 9 server.js

  1. Install the node-flint npm package to your project. This is done from the terminal window at the bottom of the Cloud9 IDE.

    npm install --save node-flint
    

    Cloud 9 npm install

    Cloud 9 npm install output

  2. Open up the package.json file and verify that the node-flint dependency is now there. Additionally, you should now see the “node-modules” folder in your application tree.

    Note: The version of the node-flint package may differ. It’s only important that the dependency is listed.

    {
      "name": "mybot",
      "version": "0.0.0",
      "description": "A Cisco Spark bot using Flint",
      "main": "server.js",
      "repository": "",
      "author": "Nicholas Marus <nmarus@gmail.com>",
      "dependencies": {
        "node-flint": "^1.0.8"
      }
    }
    

    Cloud 9 package.json updated

Run Flint
  1. Run the bot manually from the Cloud9 Terminal:

    DEBUG=flint node server.js
    

    Cloud 9 run flint

  2. Validate the logs. You should see something similar to the following. If you haven’t added the Bot to a room yet, do so now. You can add the Bot by email address to an existing room, create new room with the bot and others, or create a 1:1 chat with it. Once added, wait till the log states a room is registered. This will be within 15 seconds of the bot getting joined to the room.

    flint found a room with a node-flint but not registered +42s
    flint started polling a new repeater task queue +6ms
    flint started polling a new scheduler task queue +1ms
    flint has registered a room +2s
    
  3. Open a chat window with your bot account and run a few test commands:

    /echo hello world!
    
    I would like a beer!
    
  4. Monitor the terminal on Cloud9 for events that Flint produces.

  5. To stop the Cloud9 application, press ctrl + c from the terminal window.

Adjust Cloud9 Project Security (required only for private projects)

If you are running this as a “private” project on Cloud9 (vs public), you will need to make sure that the call back URL that is used in the creation of webhooks, is made public. To do so:

  1. Select share from the cloud9 menu in the top right hand corner.

    Cloud 9 project permissions

  2. Make sure the “application” is set to “public”

    Cloud 9 application set to public

References
  • Node Package node-flint: http://npmjs.org/node-flint
  • Node Package node-sparky: http://npmjs.org/node-sparky
  • Cloud9 Sample Project: https://c9.io/nmarus/mybot

AudioBook Review: The Goal

By Nicholas Marus

What is the Goal of a company? What is the best way to achieve that goal? “The Goal” is a book about thinking on complex problems and their solutions from a different angle. It introduces the “Theory of Constraints”, a management paradigm that views any manageable system as being limited in achieving more of its goals by a very small number of constraints.

It’s not a new book, but it is still applicable in many ways. The concepts in this book can apply to any industry or complex process in life. In addition, this may be one of the best audio books I have listened to. Normally, I’m not into audiobooks presented with multiple voice actors, but this one was done amazingly well. Even if you don’t learn anything from the topic, it is a very fun listen.

The Goal Book Cover The Goal
Eliyahu M. Goldratt, Jeff Cox, David Whitford,
Business
Gower Publishing Company, Limited
2004
384

Alex Rogo is a harried plant manager working ever more desperately to try and improve performance. His factory is rapidly heading for disaster. So is his marriage. He has ninety days to save his plant - or it will be closed by corporate HQ, with hundreds of job losses. It takes a chance meeting with a colleague from student days - Jonah - to help him break out of conventional ways of thinking to see what needs to be done.

Changing T1 Channel Selection Order to Ascending

By Nicholas Marus

This allows you to change the channel selection order to ascending. I found this necessary when doing a point to point T1 with an Intertel. Initially I had presumed that you could add the voice-port to a trunk group. This is not the case with T1’s and you have to use the cas-custom command.

controller T1 0/0/1
 clock source internal
 cablelength short 110
 ds0-group 0 timeslots 1-24 type e&m-wink-start
 cas-custom 0
 trunk-group itel timeslots 1-24
trunk group itel
 hunt-scheme sequential both up
dial-peer voice 100 pots
 trunkgroup itel
 destination-pattern ^11...$

Cisco T.37 Fax Onramp

By Nicholas Marus

So in my latest project, I got the chance to deploy the T.37 Fax Onramp config. Basically this lets a Cisco IOS Voice Gateway answer incoming faxes and relay them to SMTP destination. It’s a pretty slick idea that I don’t see too often. The config is fairly simple too. Here are the important config items:

ip domain name mydomain.local
ip name-server 10.0.0.10
ip name-server 10.0.0.11
!
fax receive called-subscriber $d$
fax interface-type fax-mail
mta send server smtp.mydomain.local port 25
mta send subject Fax-Mail Message
mta send with-subject both
mta send postmaster administrator@mydomain.local
mta send mail-from hostname myvoicegateway.mydomain.local
mta send mail-from username $s$
mta send return-receipt-to hostname mydomain.local
mta send return-receipt-to username administrator
!
application
service onfax flash:app_faxmail_onramp.2.0.1.3.tcl
!
global  service alternate default
!
!
dial-peer voice 1000 pots
service onfax
information-type fax
incoming called-number 1000
direct-inward-dial
!
dial-peer voice 1001 mmoip
service fax_on_vfc_onramp_app out-bound
destination-pattern 1000
information-type fax
session target mailto:user@mydomain.local

I’d think with a little work and some trial and error you probably could get this to front end faxes into Unity Connection. There was a way to do this with Unity Proper that would decipher the fax and route it to the correct mailbox so you did not need a smtp dialpeer for each destination. You could simply use the FAX field under the user. (or so i remeber from labbing this back in the 4.0 days…)

Also of note, there is a bug in the latest dspware that effects OnRamp. This on bug id: CSCto54549. This was only effecting my faxes from a particular opt out service. TAC has development dspware that you can use until they fix the embedded version in IOS.

 

Cisco UCCX Improved TAPS Application

By Nicholas Marus

Before I started working on a way to use TAPS without the need of UCCX, I partially re-wrote the Cisco TAPS application.

It started as a means to get e.164 support, but ended up in mostly a complete rewrite once I looked under the covers of the Cisco TAPS “aef” file. Today, I finally got around to posting this on github.

Cisco UCCX improved TAPS script
https://github.com/nmarus/itaps
0 forks.
0 open issues.
Recent commits:

ITAPS - Improved TAPS App for UCCX

ITAPS is a modification of the Cisco TAPS application used for phone registration on UCCX. This version adds some additional features and cleans up the code in the Cisco ".aef" file.

New Features: (as compared to the default Cisco App)

  • Full e.164 Support - Enter your e.164 DNs using the "#" inplace of "+".
  • Secure PIN - A PIN has been added to secure access to the application.
  • Removed Language Prompt - App uses default system language.
  • Refined overlapping DNs logic - Shared lines have been a killer for using TAPS in many rollouts. While there is some logic in TAPS to get around this, ITAPS adds a better navigation system and through some simple modifications to the BAT import process and the use of unique External Phone Number masks.

Install Method #1: (Easy)

  1. Download the ITAPS_AAR.aar file from this repository
  2. Upload it to UCCX just as you would the TAPS_AAR.aar file retrieved from CUCM

Note: This is tested with UCCX 10.0, 10.5, 10.6. The dependant files in the .aar seem to be fairly static. See the AAR folder for the AAR file source to modify as needed.

Install Method #2: (Manual)

  1. Launch the CUCM Admin interface
  2. Download the Cisco TAPS_AAR.aar file
  3. Launch the UCCX Admin interface
  4. Uploade the TAPS_AAR.aar file to UCCX
  5. Open the Prmpt repository
  6. Locate the prompt directory where the "TAPS" folder has been created
  7. Create new prompts folder called "ITAPS" and then open the folder
  8. Upload the ITAPS_Prompts.zip to this folder. UCCX will uncompress the ZIP file
  9. Open the UCCX Script repository
  10. Upload the ITAPS.aef script (found in AAR_Source/Scripts/default)
  11. Update TAPS application (built by TAPS_AVR.aar file you upoaded earlier) to use the ITAPS.aef script.
  12. Specify CUCM IP Address and PIN
  13. Define a new trigger for this app if you have not already done so.
  14. (suggested) Restart the UCCX Engine on all UCCX nodes in cluster

Prompts:

The following are the list of Prompts ITAPS uses along with a brief diaglog contained in the prompt.

  • pr_Welcome: Welcome to the Telephony Auto Provision System.
  • pr_EnterPIN: Please enter your PIN followed by the pound or hash key.
  • pr_EnterDN: Please enter the directory number that should be assigned to this phone followed by the pound or hash key.
  • pr_EnterDNagain: Please enter the directory number again followed by the pound or hash key.
  • pr_EntryDoesNotMatch: Those entries do not match. Please try again.
  • pr_ErrorDuplicate: The directory number entered is on a shared line. To identify the device, enter the phone number mask followed by the pound or hash key.
  • pr_ErrorWithCode: The error code reported was...
  • pr_Success: Operation successful. The phone will reboot now.
  • pr_Invalid_Entry: Invalid entry or time out. Please try again.
  • pr_Error: There was an error performing this operation.
  • pr_Goodbye: Goodbye

Error Codes:

  • (0) Successfull
  • (1) Protected DN
  • (2) Incomplete
  • (3) Duplicate DN
  • (5) Not a BAT Device
  • (6) Not an Auto Registered device
  • (7) Not Found
  • (8) Incomplete

 

Book Review: The Phoenix Project

By Nicholas Marus

This is another great book I’ve had the pleasure in reading recently. It is a great representation of the issues that affect I.T. and how common problems can be solved with a bit of creative thinking and common sense. It’s enlightening and entertaining at the same time.

The Phoenix Project Book Cover The Phoenix Project
Gene Kim, Kevin Behr, George Spafford,
Business & Economics
IT Revolution
October 15, 2014
384

Bill is an IT manager at Parts Unlimited. It's Tuesday morning and on his drive into the office, Bill gets a call from the CEO. The company's new IT initiative, code named Phoenix Project, is critical to the future of Parts Unlimited, but the project is massively over budget and very late. The CEO wants Bill to report directly to him and fix the mess in ninety days or else Bill's entire department will be outsourced. With the help of a prospective board member and his mysterious philosophy of The Three Ways, Bill starts to see that IT work has more in common with manufacturing plant work than he ever imagined. With the clock ticking, Bill must organize work flow, streamline interdepartmental communications, and effectively serve the other business functions at Parts Unlimited. In a fast-paced and entertaining style, three luminaries of the DevOps movement deliver a story that anyone who works in IT will recognize. Readers will not only learn how to improve their own IT organizations, they'll never view IT the same way again.

Cisco TAPS CLI Interface

By Nicholas Marus

This is a little project I have been working on to build an interface to TAPS without UCCX.

Cisco TAPS CLI interface to associate BAT DN with an Auto Registered DN
https://github.com/nmarus/tapdance
0 forks.
0 open issues.
Recent commits:

Integrating Cisco UCCX 10 with Open Source MRCP for TTS and ASR

By Nicholas Marus

So what is MRCP and why do we care?

MRCP is the protocol that UCCX uses to interface with TTS and ASR engines. Typically, this is a IBM Websphere Voice, Nuance Vocalizer, or Scansoft Realspeak server. However, the MRCP protocol is an open standard. It is possible to integrate UCCX with other MRCP compliant servers. UCCX supports both version 1 and version 2 of MRCP.

c4ef0221826630945344f38dafe8cac0

b9a76ffba012b84ec3a2c63f2a48b74d

So why all of this? Well.. simple… For one, I have always wanted a TTS/ASR  setup in my lab to work on some more advanced UCCX scripting techniques. But… more importantly…  I really just wanted  a way to quickly insert and edit prompts as I made changes to my script logic. A time limited demo of one of the commercial products really doesn’t appeal to me either, so I started looking at other unlimited/open-source options. After a little bit of digging I discovered UNIMRCP. I was able to cobble together a basic TTS and ASR server that works well with UCCX.

Disclaimer: The purpose of this how-to is to get you started. I was not able to find any one place that all of this information was compiled so hopefully this helps those who are looking for this process and a boost to get started faster than I did. This is not an all inclusive setup but will get the basics done. Additional tweaking to the server and it’s configurations files might be necessary.  You may find a quicker/better way of doing this. I have left certain details vague as this is not a UCCX nor Linux how-to. And of course… your mileage may vary.

This walks through a high-level install of 3 related open source projects and the integration into Cisco UCCX 10.

  • UNIMRCP – This is a open source implementation of the MRCP protocol. This is simply the bridge from MRCP to TTS and ASR engines.
  • Flite – This is a light open source TTS engine based on the Festival engine (Festival-Lite = Flite)
  • Pocket Sphinx – This is an open source ASR engine.

Versions used:

  • CentOS 6.5_x86_64 with latest updates as of 8/24/2014
  • UNIMRCP Deps 1.2.1
  • UNIMRCP 1.1.0
  • UNIMRCP 1.2.0
  • Flite 1.3.99 (Festival Lite 1.4 custom build by UNIMRCP)
  • Sphinxbase 0.4.99
  • Pocketsphinx 0.5.99
  • Cisco Unified Communication Manager  (CUCM) 10.5
  • Cisco Unified Contact Center Express (UCCX) 10.5

Source Packages:

Knowledge Assumptions:

  • Basic Linux
  • Basic understanding of building from source files in Linux (very minor)
  • Basic Cisco CUCM/UCCX

Notes:

  • This how-to uses MRCP version 1. Cisco UCCX 10 supports version 2 as well but then sends SSML messages to the MRCP server. Flite TTS does not support SSML messages so MRCP version 1 is used for this setup. The advantages of version 2 is that the RTP messages are streamed directly to the endpoint and it uses the SIP protocol for integration.
  • This how-to will go through compiling and installing UNIMRCP 1.2, and compiling but not installing UNIMRCP 1.1 in order to grab the plugins built from that version of the source. The 1.1 plugins are then moved to the 1.2 installation. (Note: The reason for this is that UNIMRCP 1.2 removed these plugins from the main svn trunk and into the external solutions directory. You can still download them from the svn repo and attempt to compile with 1.2 source if you choose to figure that out. I did not as I did not want to monkey around with bootstrap and the likelihood of modifying make files which would put this how-to out of the reach of most tinker’ers)
  • This build will result in a functional TTS server. The ASR components are registered with UCCX but this does not go through grammar builds and testing.
  • The included voices with Flite are 8K low quality. They did this intentionally. It is theoretically possible to add higher quality voices to the Flite source.

References:

 

PART 1: Configure UNIMRCP/FLITE/POCKETSPHINX: 

Server Setup:

The first thing you will need is a Linux server. For this setup I am using CentOS 6.5 on vmware. I initially tried with a debian build but ran into some dependency issues.

  1. Install centos 6.5 as “minimal server”
  2. Update centos.
    yum update
  3. (Optional) Install basic server tools using yum.
    yum install vim wget mlocate svn
  4. Install the prerequisite packages for a source build environment using yum.
    yum install automake autoconf libtool gcc gcc-c++ pkg-config ncurses-devel

Disable Firewall: (or alternately add rules to allow unimrcp to work) 

The default firewall blocks ports that UNIMRCP uses. For a lab environment, just disable the firewall, else, you can choose to modify iptables to allow the ports MRCP uses.

  1. Run:
    service iptables stop && service ip6tables stop
    chkconfig iptables off && chkconfig ip6tables off

Server Dependancies:

UNIMRCP makes uses of APR and Sophia-SIP libraries. The dependancies source is provided by UNIMRCP.

**Note that both APR and Sophia-SIP have been modified so make sure you use the source package provided by UNIMRCP.

As root:

  1. Download and extract unimrcp-deps-1.2.1.tar.gz to /root/
  2. Extract and install
    tar -zxvf unimrcp-deps-1.2.1.tar.gz
    cd unimrcp-deps-1.2.1
    ./build-dep-libs.sh
  3. Answer ‘y’ to both prompts.

UniMRCP Install:

Next grab the source files for UNIMRCP 1.1, UNIMRCP 1.2, Sphinx-base,  Pocketsphinx, and the Pocketsphinx model.

**Note the locations these files are being extracted to.  Some are going to /root, others to /usr/local. The files going to /usr/local are referenced by UNIMRCP after it is installed. Alternatively you can use /usr/src in place of /usr/local as “make install” is never ran on this source. It’s just best to not leave these in /root as they are required for UNIMRCP to run and should not be moved. Files extracted to /root can be safely deleted once you have UNIMRCP up and running. 

As root:

  1. Download and extract unimrcp-1.1.0.tar.gz to /root/
  2. Download and extract unimrcp-1.2.0.tar.gz to /root/
  3. Download and extract sphinxbase-0.4.99-latest.tar.gz to /usr/local/
  4. Download and extract pocketsphinx-0.5.99-latest.tar.gz to /usr/local/
  5. Download and extract communicator_semi_6000_20080321.tar.gz to /root/
  6. Download and extract flite-1.3.99-latest.tar.gz to /usr/local/

Flite Configure and Compile:

Now build the Flite binaries.

**Note that “–with-pic –disable-shared” configure option is not in the UNIMRCP Flite install wiki page. This is a workaround to enable static build on a x86_64 platform. I feel this might be related to UNIMRCP  building as x86_32 by default instead of x86_64 (unconfined) but I have not had a chance to look closer yet. See thread above under references.

As root:

  1. From the flite directory: (/usr/local/flite-1.3.99)
    ./configure --with-pic --disable-shared
    make

Sphinx Configure and Compile:

Next build the sphinx-base binaries.

As root:

  1. From the sphinxbase directory: (/usr/local/sphinxbase-0.4.99)
    ./configure
    make

Pocket Sphinx Configure and Compile:

Next build the pocketsphinx binaries.

As root:

  1. From the pocketsphinx directory: (/usr/local/pocketsphinx-0.5.99)
    ./configure
    make

UniMRCP Configure and Compile of 1.2

Now you can build and install UNIMRCP 1.2.

**Note the “make install” step installs to /usr/local/unimrcp. This is the default location. 

As root:

  1. From the UNIMRCP 1.2 directory: (/root/unimrcp-1.2.0)
    ./configure
    make
    make install

UniMRCP Configure and Compile of 1.1:

Next build UNIMRCP 1.1.

**Note that this step is only being done to get the flite and sphinx plugins. Do not run “make install” as this will overwrite your 1.2 binaries.

As root:

  1. From the UNIMRCP 1.1 directory: (/root/unimrcp-1.1.0)
    ./configure \
    --enable-flite-plugin \
    --with-flite=/usr/local/flite-1.3.99 \
    --enable-pocketsphinx-plugin \
    --with-pocketsphinx=/usr/local/pocketsphinx-0.5.99 \
    --with-sphinxbase=/usr/local/sphinxbase-0.4.99
    make

Install Plugins from UniMRCP 1.1 Build to 1.2 install:

Now that you have the plugins for Flite and Pocket Sphinx, you can move these to your UNIMRCP 1.2 installation.

**Note this would normally be done for you when running “make install” but we are simply grabbing the compiled plugins and setting up the permissions and symbolic links manually in our UNIMRCP 1.2 folder. Also note the files name change from .lai to .la. 

As root:

  1. From the UNIMRCP 1.1 directory: (/root/unimrcp-1.1.0/plugins)
    cp mrcp-flite/.libs/mrcpflite.a \
    /usr/local/unimrcp/plugin/
    cp mrcp-flite/.libs/mrcpflite.lai \
    /usr/local/unimrcp/plugin/mrcpflite.la
    cp mrcp-flite/.libs/mrcpflite.so.0.1.0 \
    /usr/local/unimrcp/plugin/
    cp mrcp-pocketsphinx/.libs/mrcppocketsphinx.a \
    /usr/local/unimrcp/plugin/
    cp mrcp-pocketsphinx/.libs/mrcppocketsphinx.lai \
    /usr/local/unimrcp/plugin/mrcppocketsphinx.la
    cp mrcp-pocketsphinx/.libs/mrcppocketsphinx.so.0.1.0 \
    /usr/local/unimrcp/plugin/
  2. From the UNIMRCP 1.2 install plugin directory: (/usr/local/unimrcp/plugin)
    ln -s mrcpflite.so.0.1.0 mrcpflite.so
    ln -s mrcpflite.so.0.1.0 mrcpflite.so.0
    ln -s mrcppocketsphinx.so.0.1.0 mrcppocketsphinx.so
    ln -s mrcppocketsphinx.so.0.1.0 mrcppocketsphinx.so.0
    chmod 755 mrcpflite.la
    chmod 755 mrcppocketsphinx.la

Pocketsphinx Config

Next, configure Pocketsphinx.

As root:

  1. Copy PocketSphinx model (communicator) files to /usr/local/unimrcp/data
    cp /root/Communicator_semi_40.cd_semi_6000/* /usr/local/unimrcp/data
  2. Create pocketsphinx.xml configuration file
    touch /usr/local/unimrcp/conf/pocketsphinx.xml
  3. Add the following to /usr/local/unimrcp/conf/pocketsphinx.xml
    <!-- PocketSphinx Document -->
    <pocketsphinx>
    <!-- Senstitivity level and timeout are used for voice activity (speech) detection
    reasonable values: level is in [2..250] range, timeout is in [100..500] msec range
    -->
    <sensitivity level="50" timeout="300"/>
    
    <!-- Default values for noinput and recognition timeout,
    these values can be overriden by client's requests
    -->
    <timers noinput-timeout="10000" recognition-timeout="15000"/>
    <!-- PocketSphinx related model and dictionary data.
    Default dir (dir="") is InstallDir/data
    -->
    <model dir="" narrowband="communicator" wideband="wsj1" dictionary="default.dic" preferred="narrowband"/>
    <!-- <model dir="/usr/local/freeswitch/grammar" narrowband="model/communicator" wideband="model/wsj1" dictionary="default.dic"/> -->
    
    <!-- Enable to save utterance.
    Default dir (dir="") is InstallDir/data
    -->
    <save-waveform dir="" enable="0"/>
    </pocketsphinx>

UniMRCP Config:

Now setup UNIMRCP server to use port 5060 for SIP,  resource map strings for what UCCX requests in it’s RTSP url,  and enable Flite and Pocketsphinx plugins.

**Note that MRCPv1 does not use SIP, however if you want to play with MRCPv2 on UCCX with another TTS engine that supports SSML, you will want to change the default port from 8060 to 5060. This configuration also sets the defaults for TTS and ASR. It is possible to use profiles in order to have multiple TTS and ASR engines running. 

As root:

  1. Edit /usr/local/unimrcp/conf/unimrcpserver.xml to match below: (bolded items are the parameters you are changing/adding)
    [...]
    
    <sip-port>5060</sip-port>
    
    [...]
    
    <resource-map>
     <param name="speechsynth" value="synthesizer"/>
     <param name="speechrecog" value="recognizer”/>
    </resource-map>
    
    [...]
    
    <!-- Factory of plugins (MRCP engines) -->
     <plugin-factory>
       <engine id="Demo-Synth-1" name="demosynth" enable="false"/>
       <engine id="Demo-Recog-1" name="demorecog" enable="false"/>
       <engine id="Demo-Verifier-1" name="demoverifier" enable="true"/>
       <engine id="Recorder-1" name="mrcprecorder" enable="true"/>
       <engine id="Flite-1" name="mrcpflite" enable="true"/>
       <engine id="PocketSphinx-1" name="mrcppocketsphinx" enable="true"/>

Run UniMRCP Server:

Now you can start the UNIMRCP server interactively to observe startup messages and validate Flite and Pocket Sphinx plugins are loading.

**Note that interactive mode will also let you see the requests from the MRCP client (UCCX) as well as the back and forth messages to the ASR and TTS plugins. This is very helpful in debugging issues with your setup. In interactive mode, the server is only running while this is executing.  If you are wanting to setup UNIMRCP as a system service (daemon), a simple rc exec script can be written or you can add this line to /etc/rc.local: “/usr/local/unimrcp/bin/unimrcpserver -d -r /usr/local/unimrcp”. 

As root:

  1. From the UNIMRCP bin folder (/usr/local/unimrcp/bin/) run:
    ./unimrcpserver
  2. To exit the server and stop interactive mode, type “exit”

**Further note that there is a MRCP client that is part of UNIMRCP. You can execute this from the UNIMRCP bin folder by running “./umc”. This would be done in a second SSH session so you could have both the server and client running simultaneously. After the client starts, you can type “run synth”  (or “run synth uni2) to test a MRCPv2 client call or “run synth uni1” to test a MRCPv1 client call.  If you do this and have changed the SIP port from 8060 to 5060 as well as changed the resource map names (as instructed above), the client server communication will fail. You will also need to edit the “/usr/local/unimrcp/conf/client-profiles/unimrcp.xml” file appropriately. Additionally, even when this is setup correctly on the client side, you will see an error for completion-cause that is related to SSML and Flite. This can be ignored as Flite can not use SSML. Both the MRCPv1 and MRCPv2 UNIMRCP client profiles used by “umc” send SSML requests to the server by default. This can probaby be changed to “plain-text” in one of the config files if you wish to see this working. Fortunately, the UCCX MRCP client uses plain-text when talking to a MRCPv1 server (which Flite can understand). 

PART 2: Configure UNIMRCP in Cisco UCCX: (Tested with 10.5 using MRCPv1)

Create ASR Provider 

First, configure you ASR provider in UCCX appadmin under “Subsystems / MRCP ASR / MRCP ASR Providers”. Specify and arbitrary number of ports (yay for no port licensing restrictions…), and OSR as the ASR grammar variant.

39b8e6a08b792d953404bda17c7261cf

Create ASR Server

Next, create your ASR Server under  “Subsystems / MRCP ASR / MRCP ASR Servers”. You can leave the default provider name. Use port 1554 (UNIMRCP MRCPv1 port) and add at least one enabled language from the list.

92f973238dcc239831f09ee27e5038f8

Create ASR Dialog Group

Now create a ASR Dialog Group under “Subsystems / MRCP ASR / MRCP ASR Dialog Groups”. Specify the provider used from the previous setup and number of channels.

2dc4e83a89663de648b24f482ecf4aff

Create TTS Provider

On to TTS. First create your TTS Provider under “Subsystems / MRCP TTS / MRCP TTS Providers”. Create a new provider and name it whatever you like. I used “unimrcp 1.2”.

2db679f1c103d14010e4ccaf36e2a8b6

Create TTS Server

Next create your TTS server under “Subsystems / MRCP TTS / MRCP TTS Servers”. Create a new server, specify the provider from the previous step and use port 1554 again. Add at least one enabled language from the list.

e7bd18cb890fd84a02529a904fe52f1c

Setup TTS Default Gender

Next verify TTS default gender under “Subsystems / MRCP TTS / MRCP TTS Default Genders”. This should already be setup to use “neutral”.

Set Default TTS Provider

Now we need to set the default TTS provider under “System / System Parameters”. Specify the TTS provider you created above.

f7f4f87ef340ec1161400ac4d8f97edd

Refresh Subsystems

The subsystems are likely in service now. If not, make sure UNIMRCP is running (either interactively or as a service) and then under “Subsystems / MRCP ASR / MRCP ASR Providers” and “Subsystems / MRCP TTS / MRCP TTS Providers” click refresh. Both should show in service and if you are watching the UNIMRCP interactive console, you should see UCCX sending RTSP messages.

Your MRCP providers should look like this:

b5f33c81a254b2171870dc737a82efb4

b67df0be0f162051992e5b4794f530a1

Your MRCP Servers should look like this:

f1d4b707ed361d631bdc03bfbe50dc2e

f4f1699421a9cb203783424cb1eb0352

**Note if you servers don’t go “reachable” and your providers don’t go “in_service”, you have a few options. One, try a reboot of UCCX. If that still doesn’t work, go back and use the UNIMRCP client (umc) to verify connectivity and services on the UNIMRCP side. Additionally verify the firewall is not running on the MRCP server and that you are using the same port numbers on the UCCX and UNIMRCP server. This can be verified once the UNIMRCP server is started in interactive mode. You should see each agent come online with the port referenced it is listening on. Also, you should see each plugin being loaded without errors. 

Create a Test Script for ASR / TTS

If everything is looking good on the UCCX side, you can now test a script. TTS is fairly straightforward to test. ASR, not so much (unless you know how to build grammar). For this exercise, I am simply testing the “ASR Dialog Group” and that the subsystem is available to the script.

When building your script:

  1. Add a “Get Contact Info” step (see screenshot) to check if the script sees ASR supported. This is a boolean value that you initially set to “false” and you should see it go “true” when doing a reactive debug.
  2. Use “Create TTS Prompt” and “Play prompt” to test TTS

d1bb17ba46291b76a61241affee5a7d2

When you create your Application for the script and define a trigger, make sure  “Override Media Termination” is selected. Once doing that, set your MRCP ASR Dialog Group as either: The only Dialog Group (my screenshot); The first Dialog Group above Default;

16c38389c839d340a24f2dc1e3365f4d

**Note that having 2 Dialog Groups in the the list will allow the script to run even when the ASR server might be down. For testing, I am only including one. With only the one ASR Dialog Group specified, you will get a busy tone if ASR is down. Don’t do this in production. 

Here is the sample script I built:

4e94cb6ecfa4b561bcc8950cb884e306

**Note that other than checking if ASR is enabled, this script performs no ASR functions. On a production system, you will want to have 2 Dialog Groups. The primary will be for ASR and the secondary is the Default (or other non ASR Dialog Group). You will want to build logic into your script that verifies ASR is online before attempting to do any ASR steps through the use of the “Get Contact Info” step and then testing of the boolean variable it sets. 

Test: (and have a beer)

You should now have a script, application, and trigger setup to test ASR and TTS. This is a video of me doing a interactive debug of the script and a sampling of the audio for TTS.

 

Conclusion:

MRCP v1 and v2 are both RFCs that Cisco has helped author. It seems to be the prevailing open standard for interfacing TTS and ASR engines with your IVR/Phone-systems. UNIMRCP is very powerful and robust open source implementation of an MRCP server. It’s the backend that many commercial products use including NUANCE, Acapela and Ceptrstal. Note that UNIMRCP is just an interface. It only facilitates the communication between the TTS/ASR engines and the MRCP client (in this case UCCX).  Flite is based on Festival which is a research project by Carnegie Mellon University’s speech group. Many other projects are based off their work. Flite’s TTS may sound very basic, but this was the intent as it was designed to be extremely light and simple for others to learn speech synthesis theory. It can be expanded with more complex voices.  If you are a coder, UNIMRCP has info on building plugins to other TTS/ASR engines so technically you can use any TTS/ASR with UCCX with a little elbow grease. Some of the commercial TTS engines (i.e. Acapela/Cepstral/ivona) have free (or close to free) developer programs that include access to UNIMRCP plugins and limited port versions of their TTS engines. Some of these are extremely high quality.

Speeding Up VMWare vSphere Web Client

By Nicholas Marus

Is the performance of the vSphere Web Cleint getting you down? Try this simple little hack that speeds up performance by tweaking the cache on Adobe Flash.

This involves adjusting the maximum allowed local storage that flash can use. By default this is a measly 100kb. YMMV.

  • Open the browser you access the web client from
  • Go here (www.macromedia.com…)
  • Click either global storage settings (for all sites) or website storage settings (for specific site)  and change from 100k to 10MB or unlimited
  • Open/reopen/refresh the vSphere Web Client page

2014-08-05_02-01-41

Cisco Live 2014, DevOps, and evolving the UC Engineer…

By Nicholas Marus

This year marked the 25th anniversary for the Cisco sponsored conference.

I was fortunate enough to be able to attend again this year. As always, I left highly motivated and invigorated for another great year of working for a Cisco partner. That alone was worth the ticket price in my opinion… but there was so much more too. There was the social networking, the amazing sessions, the Cisco sponsored appreciation events. Highlights this year was Lenny Kravitz and Imagine Dragons which gave us all a private show at the Giants Stadium (AT&T Park). All that… plus beanbag chairs everywhere… and of course all the new technology to see and play with. Thank you Cisco!

Cisco Customer Appreciation Event Lenny Kravitz and Imagine Dragons The traveling band...

Box seat view for VIPs ;)  Cisco Bean bag chairs for lounging... White DX650

One of the biggest highlights for me this year was the focus on DevOps. This is becoming a very big buzz word. It really doesn’t describe anything new (basicly development combined operations), but I like that the industry has coined something for this. It really shows an awesome movement toward development skills being applicable for more than just purely dedicated programmers. Anyone in the industry knows that this is not completely new… Sys and Network Admins have been using custom programming to build their own automation and management utilities for a very long time. The difference is that many hardware/software manufacturers are API enabling their products for an easier method of integrating custom applications into these platforms. Cisco is no different and is one of the leaders in this movement (and I’m Cisco biased so I am going to focus on them). Cisco’s Unified Computing platform and Datacenter technologies have been at the center of this in most of what is published out there. However, there are also many other initiatives that Cisco is participating in heavily. Things such as SDN and OpenStack. These are all technologies designed to provide greater flexibility and give the enterprise more control and integration possibilities.

A very neat demo Cisco had in the DevNet zone was this little model train setup that would interact with your phone and was very easy to program using a handful of sensors and actuators. This all ran atop a Cisco platform to show the flexibility of what they can provide.

DevOps demo... DevOps demo...

So how does all this fit into the world a UC focused engineer such as myself?

Good question.. I’m glad you asked…

As UC focused engineers, we’ve certainly haven’t had to know development/programming to be great at our job. Let’s take a quick look at IT in the past 10-15 years though. Historically we’ve seen that I.T. is always evolving. The jobs are getting easier and people are getting replaced by automated systems or better technology.

Hitting close to home is classic telecom. In the mid to late 90s, telecom saw the start of the movement from TDM to IP. Voice over IP was just taking off. Your traditional telecom guy soon found himself irrelevant if he didn’t expand his skillset to accommodate this change. Many had to pick up data networking, IP, QOS, various operating systems, and learn about enterprise email platforms. They also saw the move away from separate voice and data cabling. The buttset, punchtool, toner, and crimptool were now just a minor part of the toolset… if even needed. Voice and data was coming together and the converged engineer role emerged.

This is not just the only example. Desktop and server teams are starting to see this in their industry with the movement toward BYOD, server virtualization, and now virtualized desktops (VDI). System troubleshooting of app installs, drivers, bugs/viruses, and various challenges with a variety of hardware is becoming less and less part of the job. Spinning up a new server, involves a few clicks. Recovering a user’s corrupt OS is another few clicks. VDI has made it so you can pull their image back a few revs or even back to a base load without ever touching their physical system. In many cases, desktop support teams are shrinking because of this.

The “cloud” has also started to make things easier with less people. It is simplifying the rollout of applications and services to the end user or to customers. Huge organizations are moving to Office 365 for both the simplicity of license management as well as the added redundancy of now having their Exchange mail servers in the cloud. There goes the Exchange support team… Developers and startups are finding a surplus of cloud based offerings to quickly and economically spin up their apps without having to worry about the details of the underlying hardware, operating systems, or even redundancy and clustering. They can write their apps to an API and have a very robust product. Companies such as Amazon (AWS), Heroku, EngineYard and many others are facilitating this. These startup companies no longer need server or db admins on staff and can function with just developers.

So how about the UC Engineer? Yes, the guy/gal that already had to evolve from purely voice, to now voice and data and anything else it touches. How do we evolve?

Is the answer to learn more products? Cisco continues to expand its portfolio in video/telepresence… They are growing their collaboration capabilities with Jabber and Webex… They are expanding a lot of the functionality of customer contact centers…. All of these discrete products are getting integrated together (often at the cost of blood, sweat, and TAC tears). On the flip side, a lot of our day to day tasks are getting easier and quicker to deploy.  Appliance based virtualized UC is simple and here to stay.  Is “vanilla” UC in the form of  couple servers running BE6K or just simple deployments of call control and voicemail becoming junior engineer work? Do you just want to be pushing buttons to complete your installs or do you want more? Is the complexity only in the design phases or elaborate integrations? Maybe it’s things such as Cisco to Lync, or Jabber/webex to customer infrastructure such as Exchange/AD or even to external federation? Maybe it’s diving deeper into contact center technologies? Scripting? VXML? Perhaps it’s working with more third parties? ESNA? Google Enterprise Apps? Maybe the complexity is in mobility and giving users access anywhere from any device? Collab Edge?  How much of that is already point and click or  as easy as following a simple step 1-10 white paper? What’s going to make us stand out and stay relevant? What’s going to make enterprise see the value in investing in higher end products from Cisco? or from hiring higher end staff to support it? What about Cisco partners? What’s going to make their professional services relevant to enterprise?

I think the answer is UC DevOps.

If you take a look at the site developer.cisco.com, you will notice a plethora of API and reference docs for Cisco’s Collaboration product line. This has been around for a while (and it’s growing quickly). As a UC engineer, we really haven’t needed to dive into this too deep. However, is this the next evolution for us? Will this be the skill that makes us stand out as individuals? or a better question… Will bringing  these skills to the table make Cisco Business Partners stand out among their competition?

What if (as a consultant, enterprise UC engineer, or Cisco partner) you could bring to the table this DevOps know-how? Maybe its helping build a custom web app that integrates into an existing helpdesk workflow to allow pin resets for voicemail? The enterprise could now do this without needing to get the level 1 guys into the admin interface where they could screw something up. Or better, they no longer have to escalate this to a level 2 or 3 guy to perform a menial task. There is an API for that. How about a enterprise who wants to let their external customers video and/or text chat with the internal representatives over jabber? There is an API already for this too. How about building interfaces that automatically provision new users in CUCM, IM&P, and CUC without the user needing to know all the technical details around CSS, location, button templates, mailbox templates, device association, etc?  Not just Cisco Provisioning Manager… Deeper… this is about taking that interface and helping an enterprises integrate that into their existing software and make it part of the same interface they already use. Yep…there is an API for that too. How about a tighter integration between an enterprise’s web presence and their contact center? How about pulling custom metrics from the UC solution in order to provide better data to marketing about their web, email, and phone campaigns? How about helping enterprises build rich media applications that run directly on the phone?

So how do you get there? At minimum, familiarize yourself with all the APIs. Get yourself fluent enough to be able to identify problems or places for improved efficiency based on the capabilities of the systems. Help your team/clients/account managers/customers to understand the platform, the integration, the topology. Help them listen for problems or ways that these APIs can be used to add value to your solution. That’s step one and will open many other doors. If you are a consultant or partner engineer, take it a bit further. Learn a bit of programming and be able to interface with the APIs. Understand how they work in depth. Then, figure out ways to use this knowledge and skillset to make yourself and your company more relevant as this movement gains momentum.

Yes… UC DevOps… Personally I am very excited about this. This is a great direction and a good time to start honing the programming skills.

Unrestricted to Restricted Migration

By Nicholas Marus

Unrestricted to restricted version migrations are officially unsupported. No migration tools exist.

I just had the “pleasure” of doing a migration of a CUCM and CuC cluster from the unrestricted version (no encryption) to the restricted (encryption enable and restricted for export) version this weekend. It was a very manual and tedious process. A few tips if doing this yourself. This was done with CUCM and CUC 8.6.

CUCM

  • Use the Cisco BAT Export  to grab all the global config. There are a few caveats here which will make you perform the imports in a certain order. A little trial and error in the lab goes a long way.
  • Make sure you parse your config to reference all the new IP address if you are changing them. i.e, CUCM servers, description of object, URLs in enterprise parameters, URLs in phone services.
  • Import your devices and do your user updates with device and user export data massaged into the BAT.xlt device import and use update/insert tools like you would typically on a new setup. This is used instead of the import BAT as it manages insertion order. Using the import BAT will error as import does not insert all the parameters in the right order and will fail dependancies.
  • Make sure you build the new publisher servers side by side to the apps you are migrating. Do not try to sandbox the install. It leads to many issues and does not give you a easy method for side by side comparison. Do yourself a favor and disable CCM and TFTP services on the R cluster once you are sure you have everything moved over. This will keep you from having to trouble with stubborn devices that may be caching connections to the old R cluster.
  • Be sure to clear the ITL/CTL files from phones by setting the pre 8.0 migration enabled in enterprise parameter to true and rebooting your devices. Alternatively you can import the certs from the UR cluster, but this is messy IMO. Additionally note that if you are using Ext-Mobility, enabling this feature will break that. That’s not a big deal if you time everything right. If you skip this step, you will need to ht every phone manually to clear the ctl/itl or utilize a 3rd party utility that supports device macros (UPLINX/Variphy). This is not as predictable so I would try to avoid that if possible.
  • If you are using LDAP, make sure you create that integration manually on the new clusters. It seemed to break AD-sync when using the import util to create it.
  • Make sure to copy all the MOH files and install the same device packs on the new cluster. This will save time when phones switch over.
  • Make sure you have the passwords for all your application users or be ready to reset them.
  • In the end you will still need to create certain objects manually to satisfy some of the dependancies on the import with co-dependent objects.

CUC

  • Use COBRAS in briefcase mode to move CUC data. This is actually fairly easy and make a CuC UR to R migration fairly easy.
  • The one caveat… It can not migrate messages. COBRAS attaches to the CuC server using secure IMAP. No way to change that. UR CuC does not have secure IMAP. My workaround was to create a SIP trunk from the R CUCM cluster to the UR CuC so that users could still access old messages for a period of time through a backdoor DN.
  • If using SCCP integration, note that CuC will read TFTP data from the new cluster and attempt to register once this is changes. I’m not sure the exact sequence of events here, but it happened and I had two CuC servers trying to register with the new CUCM PUB.

Creating Bootable Cisco ISO Images

By Nicholas Marus

Thanks to this writeup for a cool method of getting Cisco full install bootable ISOs from non-bootable updates.

I’ve used this many a time to get servers up in my LAB when I haven’t had access to bootable ISOs yet. Below are the boot files extracted from various bootable versions of CUCM disks. It seems that only 2-4 bytes at 0xC are different. The rest of the file is identical between versions.  While putting all of this together, the hacker in me wanted to dive into what those specific bytes refer to so I got distracted for about 4 hrs while I read the ISO 9660 and El Torito specs. (No, I didn’t get far enough to figure it out… maybe another time when the ADD kicks in again. But anyway…) Here are some the bootfiles for disks I had laying around.

**This would  not be supported by TAC. Use only in LAB environments.

UPDATE 12/28/2012:

I played around a little more with this today. The bootfile extracted by UltraISO in the steps above is actually part of syslinux (specifically isolinux). This is the standard tool used to make a Linux bootable cd/dvds. The extracted file above is simply the isolinux.bin file that is used by isolinux when creating a bootable disk (inserted at sector 17). It follows the El Torito specs (part of iso9660) that isolinux uses for a non-emulated boot of a cd/dvd.

Here’s the cool thing… every Cisco ISO has a copy of the bootfile that was used to generate the El Torito boot image for the bootable version of the disk … Simply mount the non bootable ISO, grab the isolinux/isolinux.bin file and then continue to use the steps for UltraISO to add the file to make the image bootable.

2012-12-28_18-31-20

This way you don’t even need to find a working bootable ISO to steal the bootfile from or someone to post bootfiles from different versions. I went through 4 different major CUCM iso releases and compared the extracted bootfile with the isolinux/isolinux.bin file. Minus some padding at the end of the file, isolinux.bin on the disk is identical to the extracted bootfile from a bootable version.

On a side note… I’m working on a perl script to do everything UltraISO does but in mac. I hate being dependent on windows apps.

Further Reading:

 

Cisco UCM 9 to FreePBX(Asterisk 10) to Voicepulse

By Nicholas Marus

I’ve been a Voicepulse SIP subscriber of years. I love their SIP business service.

It gives me a 4 channel SIP trunk and DID service for about $12 a month plus usage. It’s cheap enough for me to use in my lab without breaking the bank. Initially when my lab was more physical and less virtual, I had the Voicepulse SIP trunks terminated on a Cisco 2801 running CME. From there, I would either register IP Phones directly or quasi-cube the connection to the occasional CUCM I would have spun up for testing. My home office phone ran off this and was mostly up when I wasn’t screwing with the setup.  That was about 6-9 months ago before I completely re-did my lab footprint to run everything virtual on MAC Mini’s.

In order to terminate my trunks in a virtual-only environment, I needed something other than a physical Cisco ISR. (Hey Cisco!!! Virtualize a CUBE!!!) What I needed was a virtual appliance to act as a SBC. Voicepulse requires either a static IP (dont have) or SIP authentication (CUCM natively does not support). I’ve been wanting an excuse to play with Acme or Sonus but neither of those were an option for me at the moment. I had some familiarity networking CUCM with Asterisk so…  Asterisk to the rescue! I decided I would try to terminate my Voicepulse SIP trunks to Asterisk, and create a SIP trunk between it and CUCM.

Asterisk 10 to Voicepulse Config

For my Asterisk server, I decided to use FreePBX. Asterisk can be installed and configured directly a top your Linux of choice, but for simplicity’s sake, FreePBX has a preconfigured installer ISO that builds the appliance for you. It’s essentially a customized CentOS load with the Asterisk packages all ready to go. You just open a browser to it’s IP when finished. For the FreePBX virtual machine, I built it as a single core with 2GB of RAM and a 16GB disk. I booted it off the FreePBX ISO and about 15 minutes later it was ready to go.

Voicepulse has a fairly decent guide on setting up with Asterisk. I used  lot of that as my starting point.  I had to tweak it a little for minor Asterisk 10 differences and lobotomize the dial-plan to support what I was wanting to accomplish with CUCM. Most of my configuration changes makes it so that Asterisk simply passes through information from CUCM and Voicepulse. I only needed to touch three sections in default Asterisk config. Trunks, inbound routes, and outbound routes.

First, create the  SIP trunk to Voicepulse.

VP-TRUNK

 

For outbound caller-id, I am leaving this blank and specifying it in CUCM (more on this later). If you wish to override this, you can do so here. For dial-plan,Voicepulse seems to want all numbers dialed as e.164. They don’t really say that in their config guides, but looking at their dial-plan examples and the plus(+) dialing in their configs, it seems so. I have only tried calling US numbers so I can’t confirm that 100%. All my Asterisk configs in this example will maintain the e.164 formats and expect CUCM to send a properly formatted e.164 number for outbound dialing.  This is why the “Dialed Number Manipulation Rules” are blank here. For the register string, use “user:password@voicepulseserver” while replacing “user” with your VP username, “password” with your VP password, and “voicepulseserver” with the specific VP server you are registering this trunk to (i.e. jfk-primary.voicepulse.com).  See the Voicepulse Asterisk setup guide on their website if this is vague.

Optionally, you can also create a secondary SIP trunk using the same setting above but placing the Voicepulse backup server (i.e. jfk-secondary.voicepulse.com) in the appropriate fields.

Next, you’ll want to create an outbound route for this trunk. This will route dialed numbers to the SIP trunk.

VP-OUT

This should be fairly self explanatory. Since I am doing all my digit manipulation in CUCM, I am just routing +1NXXNXXXXXX to the SIP trunk(s) I created above. Other that matching on +1 NANP dialing plan only (no international) it is passing everything through from CUCM as dialed without discarding or prepending any digits.

Now on to the CUCM SIP Trunk…

Asterisk 10 to Cisco Unified Communications Manager 9 Config

This took a little more trial and error. I read few a guides and perused configs others had used and cobbled this together. It may have redundant or unnecessary options, but with all the testing I have done so far, everything seems to work as it should.

In Asterisk, create a trunk as follows.

CUCM-TRUNK

Just like with Voicepulse trunks, you don’t need to specify any routes here as that will be done in either CUCM or through Asterisk routes. Note that the 192.168.10.46 is the IP address of my CUCM server. You must use the IP address of CUCM as the user context and fromdomain.

Next, create a inbound route to direct our Voicepulse DID to our CUCM.

VP-IN

I am specifying my exact DID here. Voicepulse presents me an 11 digit number and this “DID number” field  has to match what they are sending me.  I only have one DID with Voicepulse. If I had a block of DIDs, I wouldn’t necessarily need to create individual inbound routes because Asterisk supports wildcards in the form of X or N (where X = any number and N = 2-9) or bracket ranges ([1-4]). Example – if i had 17705551000 – 17705551099, I could use 177055510XX as my “DID Number” that I am routing to CUCM.

When the call gets to CUCM, Asterisk will pass this DID through.

Cisco Unified Communications Manager 9 to Asterisk 10 Config

If you are familiar with Cisco Communication Manager, you can probably skip some of this. In fact, I’m probably not going to go into a lot of detail here as the design on the CUCM side is so subjective to what you are using it for. I’ll briefly hit on my partitions and css’s along with my IP Phone config but that’s ancillary to this config.

For this example, I have 3 partitions on my CUCM server:

part

I also have 3 calling search spaces configured as follows:

css3

css1

css2

 

Not too much you need to do on the phone, but I’ve included the parts that I used for this setup.

phone

dn

enm

First, create a SIP Security Profile. You can either edit the default, or create a new one. I have created a new one. Make sure you pay close attention to the items circled in red.

CM-SIP-SEC-PROFILE

Next, create the CUCM side of the SIP trunk to Asterisk.

CUCM-TRUNK-1

Note that MTP is required. Make sure you have one in the null MRGL or in the MRGL you assign the trunk. I am using the Cisco software MTP that’s part of CUCM for my setup.

CUCM-TRUNK-2

CUCM-TRUNK-3

Make sure you specify the correct SIP Security profile and define the IP address where Asterisk is running. Save and reset the trunk.

Next create a route pattern pointing your outbound routes to this SIP trunk. This is where YMMV and where you will need to know how you want the Cisco IP phones to dial. Your desired end result is that you are sending a +1[2-9]XX[2-9]XXXXXX pattern to the SIP trunk. For my setup, I wanted to dial a 9 and get secondary dial-tone. followed by 10 digits for the local numbers in my area, or 1+10digits for long distance.  The way I chose to do this was with 4 route patterns.

First the LD pattern. Pay close attention to the transformations.

CUCM-ROUTE-1

And then 3 Local patterns matching on the 3 local area codes for Atlanta. (Only 404 shown in the screenshot)

CUCM-ROUTE-2

Notice in both of these that “Use calling Party’s External Phone Number Mask” is selected. On the IP phone, I have my Voicepulse DID assigned as the “External Number Mask”. This checkbox on the route pattern is what forwards this information to the SIP trunk and eventually to Voicepulse. Doing it this way would allow me to have multiple Voicepulse DIDs in the future and allow me to send the number of the phone I am dialing from across the trunk to Voicepulse. This way the Caller-ID on the destination caller’s phone correctly matches the DID the call is coming from.

At this point, you should be able to make outbound calls from a Cisco attached IP Phone through Asterisk to Voicepulse. All that is remaining is routing the inbound DID to your IP phone of choice. To do this, add a translation pattern to translate the 11 digit DID from Asterisk to the extension inCUCM.

It will look something like this.

CUCM-XLATE

Notice here that the “Translation Pattern” is the 11 digit DID from Voicepulse and the “Called Party” is  extension of the IP phone you want to route the call to.

At this point, you should be able to receive both inbound and outbound calls to your Cisco IP Phone.

Cisco Nexus 7000 NX-OS/IOS Comparison Tech Notes

By Nicholas Marus

This is a must read for anyone who already understands IOS and wants to jump into NXOS.

docwiki.cisco.com

 

MAC mini ESXi Custer (5.1a)

By Nicholas Marus

Over this weekend I had the chance to play in my VMWare lab at home a bit.  Earlier this year, I was able to cobble together a small lab using mac mini’s.  I originally did this with VMWare 5.0 but I’ve been wanting to play with 5.1 for a while now so I decided to go ahead and upgrade this weekend. I also respun an iso that includes the network drivers needed for mac mini on ESXi 5.1a.

(Let me preface this this with that I am not a VMWare specialized guy. I touch it a lot at work but it’s extremely superficial. YMMV on what I write below)

After reading through some of VMWare’s kb, I found that there are a few ways of going from 5.0 to 5.1. I ended up trying two complete different ones just to learn a little. Plus, I wanted to keep my users happy… (Ok, other than maybe a minecraft server for my kids and a few of their friends, there really isn’t any “mission critical” apps running in my home network. I wanted to  minimize any downtime while I did the upgrade to get some idea of what’s involved. Five nines FTW.)

Method 1: VmWare Update Manager (VUM)

So according to the link above, VMware’s recommended method is using the VUM. Ok, easy enough… I remember using something similar to this when I upgraded from 4.0 to 4.1 a few years ago. Just an app you download, ran, it connected to the host, downloaded the upgrade files, upgraded, rebooted, done, easy. I didn’t use this when I went to 5 as I was needing to slipstream drivers into the installer (mac mini) and was starting a new cluster anyway. Well…it’s not as simple anymore (or at least I couldn’t find the old updater method anymore). The VUM is now a persistent server app, requires a 64bit server OS (that’s not a dc), and a full on database instance (express for smaller installs).

Initially, I was frustrated after finding this out… but… I read some more about the process and this actually ended up being pretty cool. VMWare was able to integrate the VUM into vcenter and the esxi client. After spinning up a 2008 server and upgrading the vcenter appliance from 5.0 to 5.1a, the install of VUM was fairly straight forward. I might add that I am using the vcenter appliance and not the windows server version). I’d guess that most orgs use the normal vcenter server and already have a dedicated 2008 running there. Following this logic, it makes sense that you find the VUM installer on the ISO for the windows version of vcenter. Fortunately for me, VUM works with the appliance version too.  During the install you just point it at your vcenter appliance ip and it does the integration for you.  On the esxi client, a plugin is published that you select and download from the plugin menu. This adds several admin screens to esxi client to let you build profiles for updating your hosts. It allows you to not just do major updates (i.e. 5.0 -> 5.1), but also lets you setup polices for pushing out minor patches. Using this method I was able to migrate 2 of my 3 mac mini’s over to 5.1 with no issue.

I wasn’t sure if it was keeping the Broadcom drivers for the ethernet that I originally embedded in the 5.0 installer, or if 5.1 simply had those drivers natively now, but everything worked fine.  I may never have found the answer to how that worked if one of the mac minis didn’t like the automated process. So on to method 2… manual upgrade…

Method 2: Manual install from host console

So this is VMWare esxi 101. Boot off install CD, configure, reboot, done. If the installer finds a preexisting install, it will upgrade it for you. Nothing magical here. In my setup though.. I am running on non supported hardware. When I did 5.0, I had to embed drivers in the ISO so that the installer could see the NIC and load up. Would I need to do this with 5.1 ?

Attempt number one involved attached a usb DVD drive (apple) and just booting off that. Maybe I’d get lucky and 5.1a has broadcom drivers already. The install went normal, I was able to pass all the validation steps and it looked like it saw my NIC. Yay. Easy. Well…not really. After the install finished, the host rebooted, I set my ip addresses… but no network connectivity. VMWare said the link was up… my switch said the link was up… no connectivity. Well shit… Apparently the VUM maintained drivers during the upgrade. Manually did not.

So I went back (after I got a beer), got the updated version of the ESXi customizer (2.7.1) and respun my ISO using 5.1a as the source and the same broadcom driver bundle I used with 5.0.

 

ESXi Redhat/CentOS Template Clone problem

By Nicholas Marus

After setting up a template for CentOS 6.2, I noticed that when template’d and then later cloned, the NICs would get renamed from eth0 to eth1, eth1 to eth2, etc. This was causing the config  in the template for eth0 to get ignored. This behavior was due to the way Rhel/Cent identifies the hardware with udev (device manager for linux 2.6.x). When vmware clones a template or vm, it changes the mac address. When udev loads, it sees the new mac, thinks it’s new hardware and creates a new device eth1. The old eth0 config persists but is disabled since that is no longer visible to the system.

The simple fix is to delete /etc/udev/rules.d/70-persistent-net.rules, modify /etc/sysconfig/network-scripts/ifcfg-eth0 (remove the hw-address line), and then reboot the vm after you clone. Not very pretty but it works.

An better solution is modify your template vm. This is similar to the above steps, but instead of the final reboot, shut the template vm down and then convert to template at that point. Going forward, machines cloned from this template will now re-create the eth0 device on initial boot when udev loads.

Note that if you run multiple NICs on your vm template and want to make sure they get assigned to specific ethNs, you will still need to modify the ifcfg-ethN files and set the new hw-address that vmware assigns when creating from the template. This shouldnt be an issue to most as usually you are adding teh additional NICs after the VM has been created from the basic template.

MAC mini ESXi Custer

By Nicholas Marus

So like most geeks in IT, I have a home lab. The problem with mine is… it is loud… and it is HOT… Recently I purchased a mac mini, popped 16GB in it, and attempted to use this to get a quiet, low power, low heat esxi host. Unfortunately the default boot image of esxi did NOT recognize the integrated gige nic.  A little research led me across a program called the esxi customizer. This allows you to modify the esxi iso that you download from vmware to include other drivers. And boom… It loaded.

 

Since this was such a success, I’ll  slowly be switching out all my other rack mounts for mini’s. I”ll take a little performance hit (maybe, older cores were core 2 and gen 1 i7’s, this is all sandybridge), and drop the segmented storage network, but with the power, heat and noise savings, it is worth it. I already have compact SANs in the form of a QNAP SS-839 Pro and TS-439 Pro that I use to iscsi attach the esxi hosts so I can play with DRS/FT/Vmotion/Storage Vmotion. What I’ll end up with  is a 3-4 node esxi cluster with 2 iscsi SANs that is quiet, fast, cool, and about 6U in height for less than ~$3,500

Also of note, I was using my thunderbolt attached monitor to set this guy up and saw that esxi recognized the thunderbolt gige nic as well. This makes me think that when Apple releases the thunderbolt gige adapter in September, I should have no problems adding an additional NIC(s) and regain my dedicated storage network for esxi.

If anyone wants a shortcut to creating all this yourselves, I have posted the ISO I used along with a util that can copy this to a thumb drive so that you can USB install esxi.

http://dl.dropbox.com/u/23768/ESXi-macmini-022612-usb.zip

Also many thanks to this post for making this all possible: communities.vmware.com

Cisco IOS Shortcut Keys

By Nicholas Marus

Ctrl + A Beginning Line
Ctrl + B Backward Character
Ctrl + C Clear line
Ctrl + D Delete Character to the Right
Ctrl + E End Line
Ctrl + F Forward Character
Ctrl + H Backspace Character to the Left
Ctrl + I Refresh Line and Goto End
Ctrl + J Return
Ctrl + K Delete everything on the Right of cursor
Ctrl + L Refresh Line
Ctrl + M Return
Ctrl + N Next Command
Ctrl + P Previous Command
Ctrl + R Refresh Line
Ctrl + T Flip Last 2 Characters
Ctrl + U Clear Line and Put in Buffer
Ctrl + V Allows A Control Character To Be Typed
Ctrl + W Delete Word Backwards and Put in Buffer
Ctrl + X Clear Line to the Left and Put in Buffer
Ctrl + Y Paste Buffer Contents

Configuring a Windows Server as NTP Source

By Nicholas Marus

Open regedit and modify the following two keys. This will enable NTP as part of the Windows Time Service.

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/
Services/W32Time/Config/AnnounceFlags

Set the ‘Announce Flags’ registry entry to 5, to indicate a reliable time source.

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/
Services/W32TimeTime/Providers/NTPServer/Enabled

Changing the ‘Enabled’ flag to the value 1 enables the NTP Server.

Book Review: The Power of Habit

By Nicholas Marus

I just finished “The Power of Habit” by Charles Duhigg. I was very reluctant to start this book, but once I did, I could not put it down.

This is one of those books that I immediately wanted to read again. I would easily place it in my “Top 5 most important books I have ever read” list. Duhigg does a great job explaining the topic. He dives into a complex subject with a very clear way of explaining it while also applying it to everyday events. The stories and the way he biographies various people and companies makes the topic very relatable and also demonstrates the validity of the research and practices he is describing.

The Power of Habit Book Cover The Power of Habit
Charles Duhigg
Business & Economics
Random House Incorporated
2014
383

Identifies the neurological processes behind behaviors, explaining how self-control and success are largely driven by habits and providing guidelines for achieving personal goals and overall well-being by adjusting specific habits.

❌