Telepresence SW CE8

Cisco released new software for SX series Telepresence endpoints a couple of month ago. That SW introduced wireless desktop sharing from PC and MAC.
Here are some features of this innovation
1) To enable BYOD (that is Proximity) there is no need to login to endpoint’s web interface and search for hidden BYOD configuration parameter. There is separate menu”Proximity” for it. Moreover, it’s provisioning now is available from CUCM’s device page:

222So now we can use BAT to enable Proximity on all devices.

2) The Proximity software for desktop can be downloaded from  https://proximity.cisco.com/. But unlike the Proximity for Android or IOS desktop version allows you to share content only.
3) My DELL laptop refused to connect to my SX10 until I switched off Wave MaxxVoice which tampered with built-in mic. So in order to use you have to train your staff to turn off every mic enhancement on their laptops.
4) As with Proximity for mobile desktop version listens to ultrasound and extracts codec’s URL from it. Then it connects to is via HTTPS. The desktop capture also uses TCP 443 for transferring images.
5) Current version doesn’t show mouse cursor while sharing desktop. According to Cisco community they are going to fix it in next releases.

6) The image of CE software is pretty big and uploading and extracting cop.sgn file caused my CUCM server CPU utilization to reach almost 100%, so it’s better to do it during off-hours.

Cisco TMS, TMSPE and CMR

Collaboration Meeting Rooms by Cisco is a wonderful collaboration tool I first heard of during the latest Cisco Connect in Moscow.
I think of it as an e-mail, but for video or audio conferencing: everyone have their own URI (e.g. a person with email address of johndoe@example.com might have a CMR johndoe@cmr.example.com) that can be accessed from a number of devices like browser via Jabber Guest,desktop and mobile clients like Cisco Jabber 4 Win/Mac/Android/IOS, video codec or desktop phone.

For this to work you should have CUCM, IM&P, Telepresence Conductor and Server, TMS and TMSPE. Also Cisco suggests to adopt Personal Multiparty licensing but you can stay with Screen licensing as well.  Documentation about installation of Telepresence Conductor and Server and integrating them with CUCM is rather thorough. But I personally can’t say the same about TMS/TMSPE/CMR deployment guide. So I’d like to cover some things I encountered during implementing CMR 5 in TMS with Conductor, CUCM and Server already installed for AdHoc and Rendezvous conferencing.

1. TMS installs on a Windows Server  2012 (CUCM once was a Windows appliance as well), so it’s a good idea to have this server to be a part of the domain, as IIS which serves a GUI for configuring CMR uses windows authentication.
2. If you are planning to install 2 TMS for redundancy you should use separate MSSQL server for tmsng (and others like tmspe,tms_userportal, tmspe_vmr) databases. Cisco also specify MSSQL versions you should use: Microsoft SQL Server 2012
All versions, 64 bit only or Microsoft SQL Server 2008 R2 All versions, 64 bit only
3. If had you configured TMS already, but found that you had accidentally connected to the wrong MSSQL server there is an application named TMS tools installed along with TMS that can change db connection details.
4. When installing TMSPE you might get a Java error – it happened to me when I had JREv8 installed. After downgrade to jre-7u80-windows-x64 the problem gone
5. When TMSPE is installed you may ‘connect’ it to TMS with Administrative Tools -> Configuration -> General Settings ->  Provisioning Mode: -> Provisioning Extension
6. All your users by default would be able to access Smart Scheduler, which is great but it has so many limitations, like you cannot add non-Cisco-codec destinations (this codecs should be present in TMS) to scheduled conference. So if you don’t want to confuse them it’s better disable Smart Scheduler until it becomes more feature-rich: Administrative Tools -> User administration -> Default System Permissions -> uncheck ‘Book’ check-box against Group Name ‘Users’
7. If you want users to access CMR configuration you should import users to TMSPE. I use LDAP for that. LDAP or AD import mappings to TMSPE can be configured here: Administrative Tools -> Configuration -> Provisioning Extension Settings
The import itself is configured under Systems -> Provisioning -> Users -> User import. Also it’s nice to have Video Address Pattern and Device Address Pattern configured under User setting in a form of {username}@cmr.example.com
8. Next step should be adding of Telepresence Conductor under Collaboration Meeting Room Templates (click TelePresence Conductor Settings and specify it’s address and admin credentials). TMSPE support only one Conductor, but it’s okay
as TMSPE only pushes CMR configs and doesn’t process calls so it doesn’t need as much redundancy as Conductor.
9. To configure a template click to New Template, choose a TelePresence Conductor configured earlier, SIP alias pattern in a form of {username}@cmr.example.com, Numeric alias pattern if you want CMRs to be accessed from phones with dialpad only (I used a prefix like *1* to distinguish CMR numbers from internal DNs).
Other interesting parameters are Allow Guest Role and Guest Lobby: it allows users to share their CMR numbers and aliases with others and invite them to their CMRs, so when a guest joins your CMR it just dials # and waits for a host to connects while looking at a lobby screen.
10. If you want users to connect to their CMRs add a SIP route pattern of cmr.example.com and *1* Route pattern pointing to SIP Trunk to Conductor used to start Rendezvous conferences in CUCM.
11. CMR are populated to Conductor by TMSPE only when a users access CMR configuration page at http://<tms_fqdn>/tmsagent/tmsportal/#home and finally configures it (assigns a PIN and an optional name). You can check if CMR is there in Conductor goto it’s admins interface Status ->  Collaboration meeting rooms and search for a CMR in a form of johndoe@cmr.example.com.

In essence, there are so many nuances when deploying CMRs and I think that Cisco should include the overall description of this technology into top-level design documents like Collaboration SRND.

URI dialling in UC infrastructure. Part 3.

In previous parts I’ve tried to cover the process of configuration of egress B2B URI calling. Now it’s time to set up inbound one, so your organization will have a URI in form of info@example.com and it can be dialled by outside partners. For my scheme to work you should have CUCM, a Expressway-C/E pair and Telepresence Conductor with confbridges up and running and capable of handing rendezvous conferences.
Let’s create a search rule on Expressway-E which will accept our URI and send it to Traversal zone toward Expressway-C.

34

On Expressway-C we are going to transform info@example.com on its way from Traversal Zone to 7777@cucm1.example.com and send it to Neighbor Zone pointing to CUCM

54

Assumed we have a Telepresence Conducter setup according to http://www.cisco.com/c/dam/en/us/td/docs/telepresence/infrastructure/conductor/config_guide/xc3-0_docs/TelePresence-Conductor-Unified-CM-Deployment-Guide-XC3-0.pdf
all we have to do is to create a route pattern of 7777 pointing to a SIP trunk for rendezvous conferences.

On Telepresence Conductor let’s create a separate alias of 7777 which refers to a template External B2B

123

Template External B2B should among other parameters have a pin set.

1111

So when a remote party calls you they will see a standart Cisco background with a Example.com label and will be asked to enter a PIN via DTMF.

Of course all this setup is irrelevant if you don’t have DNS SRV records for your domain visible from public Internet.

And remember all these call will requeire a RMS licences on Expressway-C/E pairs.

URI dialling in UC infrastructure. Part 2.

As soon as your endpoints – codecs and Cisco Jabber client – are registered to CUCM and ready to dial each other URIs it’s time to try dialling to an external URI,
that is outside our enterprise. External URIs could be one of the following types:
1) a normal SIP URI in a form of info@example.com where example.com domain has appropriate SRV records (_sip._udp SRV 0 5060 host.example.com. for example for SIP over UDP)
2) a SIP URI in a form of info@1.2.3.4 with an IP address in place of the domain
3) an IP address – usually guys with Polycom systems use it along with H323 protocol.
4) exotic URIs like 1.2.3.4##12345 used also by some Polycom systems – they usually can be accesses by a standard URI of 12345@1.2.3.4 or by IP 1.2.3.4

If you have only CUCM in your network you can dial only type 1 and 2. For that case you can create a SIP Route Pattern with domain routing for type1 and with IP routing with type2. I can’t definitely say why CUCM has there two flavours of SIP route patterns – my guess is that IP address notation of 192.168.0.1 can bee seen by CUCM as a domain with 4 levels and it tries an SRV lookup (for _sip._udp.192.168.0.1) instead just using this IP address for network layer.

In order to cover all possible destinations – all types of URIs and both signalling protocols – it’s better to have an Collaboration Edge servers installed. They come in two versions: VCS-E/C which supports registrations of endpoints and
Expressway-E/C which relays endpoint registrations to CUCM in case of MRA.

So, first you need a SIP route pattern *.* with domain routing in CUCM pointing to a SIP trunk (a Route list in my case as I have a clustered pair of Expressway and two SIP trunks).

1

According to this document http://www.cisco.com/c/dam/en/us/td/docs/voice_ip_comm/expressway/config_guide/X8-2/Mobile-Remote-Access-via-Expressway-Deployment-Guide-X8-2.pdf on page 30 you have to have a new  SIP Trunk Security Profile with non-standard SIP listening port for Expressway-CUCM integration to work.

This route pattern easily covers type 1 URIs. In order to dial type 2 URIs you should add a separate SIP route pattern with IP routing and specify exact IP address (and I don’t know the way to make it more flexible now).
To cover type 3 URI we will convert IP addresses to URIs with some user training and special search rules on Collaboration Edge servers.

On Expressway-C I’ve created a separate from automatically created MRA zones neighbour zone toward CUCM.

2

And configured a search rule for URI dialing. When a requests is received from CUCM Expressway-C just sends it to Traversal zone (and my traversal zone is SIP only). That shoud cover type 1 URIs

3

For dialing by IP (type 3) IP I’ve found a post http://www.ucguerrilla.com/2014/02/cisco-telepresence-endpoints-and-ip.html which suggested a using special type of URI for that.
You should instruct your users to dial 192.168.0.100@ip.local to reach external endpoint 192.168.0.100 – this effectively converts pure IP dialling to standard URI dialling.
When the request with 192.168.0.100@ip.local reaches Expressway-C the transform would convert it to IP address

4

Then for type 2 and type 3 (converted to IP address by transform)  URIs there is a separate Search rule:

6

Moreover under  Configuration -> Dial plan -> Configuration Calls to unknown IP addresses should be set to Indirect on Expressway-C for it to work.

On Internet facing Expressway-E acting as traversal server I set up a DNS zone and a search rule with pretty standard configuration.

7

9

It will deal with type 1 URIs making DNS SRV and even DNS A/AAAA lookups for H323 and SIP.

But in order to support both SIP and H32 you should have H323-SIP Interworking Gateway option key installed, and SIP-H323 interworking  turned on under Configuration -> Protocols -> interworking. And you don’t need a DNS zone for IP dialling (both type 2 and type 3) as it will be covered by option Configuration -> Dial plan -> Configuration Calls to unknown IP addresses set to direct.

Ad-Hoc conferences with Cisco Telepresence

Recently I’ve been troubleshooting an issue with ad-hoc videoconferences in Cisco Telepresence.
Cisco Telepresence as described in this document http://www.cisco.com/c/dam/en/us/td/docs/telepresence/infrastructure/conductor/config_guide/xc3-0_docs/TelePresence-Conductor-Unified-CM-Deployment-Guide-XC3-0.pdf
is an infrastructure for creating ad-hoc, rendezvous and scheduled tightly coupled (that is controlled by a central call processing engine/mixer entity) conferences (opposed to loosely coupled conferences using built-in bridges).
Configuration of this system introduces a second B2B user agent – TelePresence Conductor (the first one is CallManager). Moreover, apart from communicating via SIP CallManager (CM), Conductor (TC) and Telepresence Servers (TS) (audio/video mixers themselves) communicate via XML RCP and exchange system parameters and Conference URIs.

In my setup ad-hoc conferences were shutting down in a couple of seconds after starting. So I decided to investigate how they are formed.
According to RFC 4579, when there is an active call between endpoint A and endpoint B and A wants to transfer this call into conference with endpoint C the following occur
1) While on call with B, A sends SIP INVITE to the focus (a conference mixer) with unique conference URIs
2) Focus replies with 200 OK and isfocus suffix in Contact field
3) Then after exchanging some information regarding the conference by SUBSCRIBE/NOTIFY (usually SUBSCRIBE package allows the exchange of conference names and connected parties in a form of XML) A sends SIP REFER to the focus and asks it to Refer-to B and replace B‘s calls with the new one
4) The focus replies with 202 Accepted and 100 Trying and send INVITE to B with Conference URI and asks to replace its current call with the new one.

5) The same steps are repeated for a call from A to С, thus inviting endpoint C to the same ad-hoc conference

Another way to do extend a call of A is to instruct the focus to send INVITE to B from a conference which is already started by A. This procedure can be repeated to extent this ad-hoc conference to C.

The implementation by Cisco looks like this
1) A is on a call with B. A in my case is a Cisco Jabber for Windows.
2) A wants to add a concurrent call to C to an ad-hoc conference (for A,B and C to be in one conference room)
3) A sends REFER to CM with Content-Type application/x-cisco-remotecc-request+xml which states that conference softkey was pressed and transmit A-B and A-C call IDs.
4) CM make a XML RPC (remote procedure call) to TC for a conrefence.create function and gets Conference URI.
5) CM sends in-dialog INVITE to B with delayed-offer SDP connection info 0.0.0.0 thus putting this endpoint on hold.
6) CM sends UPDATE to B with Contact parameter isfocus
7) CM sends INVITE to TC with conference URI it got from XML RPC. TC chooses available TS and relays INVITE to it. When it gets the responce from TS, TC relays it to CM
8) CM sends in-dialog INVITE to B with delayed-offer SDP connection info of TS IP thus connecting B to the mixer.
9) Asyncronously CM send INFO to B with XML which lists all connected parties with their respective Caller IDs
10) Steps from 6 to 9 are repeated for C at the same time.
11) TS periodically re-INVITES endpoint A,B,C with updated SDP if needed.

So Cisco Telepresence uses its own API to get conference URI and relies on the package application/x-cisco-remotecc-request+xml for signalling of conference start.
The issue with shutting down of ad-hoc after 10s was caused by software bug in TC, which terminated session in step 7 when KPML as a method of sending DTMF was signalled to it by CM instead of RFC2833.

PS. I’ve found a wonderful blog https://andrewjprokop.wordpress.com/ with a lot of posts describing SIP building blocks.

NAT and firewall traversal for SIP and H.323.

NAT

NAT translates the private IP addresses inside the enterprise into public IP addresses visible on the public Internet. In most cases NAT is combined with firewall into one device.

NAT is classified in two ways:

  1. mapping
  2. filtering.

NAT mapping can be endpoint independent, when it uses same external mapped address (or rather a combination of IP address and port) for packets from a device behind it, which are destined to different endpoint in the internet.

Example
Internal endpoint sends a packet with source IPi:Pi and destination IPe1:Pe1 and to destination IPe2:Pe2 (IPi – internal endpoint IP address, IPe1 and IPe2 – external endpoints #1 and #2 IP addresses, Pi, Pe2, Pe1 are correspondent transport layer ports).
NAT statically maps IPi:Pi to IPnat:Pnat in both cases, so external endpoint #1 gets a packet with source of IPnat:Pnat and destination of IPe1:Pe1 and #2
with same source of IPnat:Pnat and destination of IPe2:Pe2

In contrast there is an endpoint dependent mapping where NAT maps IPi:Pi to IPnat1:Pnat1 for endpoint #1 and  to IPnat2:Pnat2 for endpoint #2

NAT filtering can be Endpoint-independent, Address-dependent and Address- and port-dependent.
Endpoint-independent filtering allows any internal endpoint with any source port to communicate to internal endpoint once NAT binging is established by the latter.

Example
Internal endpoint send a packet with source of IPi:Pi to destination of IPe1:Pe1 to external endpoint #1.
NAT translate IPi:Pi to IPnat:Pnat. External endpoint #1 send a packet back with source of IPe1:Pe2 to NAT IPnat:Pnat and packet goes through NAT and reaches internal endpoint.
At the same time external endpoint #2 can send a packet destined to the same IP:port pair (IPnat:Pnat) and NAT would allow it to pass and eventually reach internal endpoint too.

Address-dependent filtering won’t allow this situation. It won’t let a packet from external endpoint #2 destined to IPnat:Pnat get though. However it would let external endpoint #1 to establish a new session with source of IPe1:Pe3 toward internal endpoint.
Address- and port-dependent filtering will close this breach – only one bidirectional session is allowed in this case.

Most of NAT devices are using endpoint-dependent mapping and address- and port-dependent filtering and are called symmetric NATs.

NAT complications for IP telephony.

1) External endpoint cannot connect to internal endpoint until the internal one creates a NAT binding.
2) SIP signalling carries an information of what IP address and port to use. So when lower network protocols tampers with IP address and ports SIP negotiations fails.
3) NAT bindings times out and can be restored only from behind the NAT while SIP endpoints can be both servers and client in a SIP dialog and rely on the fact that any of them can start a transmission.

Solutions

There are a number of solutions that can be applied in different situations.

NAT ALG

In addition to creating a binding NAT can inspect a call signalling and fix it appropriately. But you must be sure that your NAT device firmware is up-to-date with all signalling protocols. Moreover it cannot work with encrypted traffic so forget about secure SIP.

Rport and comedia

RFC 3581 gives support to a rport parameter in SIP Via header which instructs a remote endpoint to send signalling to destination if got from network layer.

Example
Asterisk has a a nat=force_rport and nat=comedia arguments in sip.conf which instructs it to use network layer information instead the one it got in SDP for communication with an endpoint. Comedia in this case is for media (RTP traffic) and Rport is for signalling traffic.

Straight SDP tampering

If an endpoint during its configuration knows what it’s external address would be it can construct SDP appropriately.

Example.
Asterisk has externip=XXX.XXX.XXX.XXX statement where you can define what address to use in SDP offer.

STUN

But what if you don’t know the external address, or your endpoint doesn’t allow to edit SDP like in p.3. There is STUN for it.
Internal endpoint connect via UDP 3478 to a STUN server in external network. STUN sees how internal endpoint address got transformed by NAT and inform the endpoint about it in reply. So the endpoint can implement SDP fixup with relying on this information.
But in case of symmetric NAT it won’t work because NAT mapping would be different and random when the endpoint start to communicate with another device. Moreover STUN (Simple Traversal of UDP through NAT) is for UDP and not for TCP. And SIP over TCP is more desirable in when SIP messages can be long when implementing video calling and especially video conferencing.

TURN

TURN (Traversal Using Relay NAT) server is a signalling and media relay entity situated outside the NAT in a DMZ. Once an internal endpoint connects to a TURN server it creates a binding of endpoints source address to its routeable interface and informs the endpoint about it. Then it just proxies all media and signalling traffic.
The downside of this approach might be an increased delay and an excessive load on TURN server hardware.
Now TURN is considered as a part of STUN IETF draft.

ICE

Interactive Connectivity Establishment (ICE) allows endpoints decide which address to use for communication. Endpoint are aware of their local IP address, they can get
additional candidates from STUN and TURN servers or by UPnP.

Example
When the remote endpoint receives the list in the SIP INVITE, it replies with a list of addresses obtained in a similar manner. Each endpoint proceeds to attempt connectivity to the addresses provided by the other endpoint by sending STUN messages to each address. In this mode, the endpoints themselves must implement STUN server functionality and respond to STUN request messages from the other endpoint. When an endpoint receives a STUN return message, it knows that it has found an IP address that permits connectivity. Each endpoint chooses the highest-ranked address that offers connectivity to the other endpoint. Then the SIP endpoints exchange INVITE messages again, this time using the addresses obtained during the connectivity-testing phase.

UPnP

UPnP-aware endpoints can make a request to UPnP-aware NATs to open certain pinholes or create bindings, thus making itself aware of routeable public address.
But only a few endpoints (A PC with Windows XP installed being one of them) support UPnP and even fewer NATs do that. Moreover using UPnP presents a possible security risk.

Assent and H.460

Assent is a Cisco proprietary protocol which presents a solution for NAT (and firewall) traversal for H.323 and SIP communications (both signalling and media).
H.460 is an industry standard and a successor to Assent, but is supports only H.323 while preserve the whole idea of Assent.

H.460 consists of three major parts: H.460.17 and H.460.18 for signalling and H.460.19 for media traversal.
In most cases it needs a Traversal client behind the NAT/FW and a Traversal Server in DMZ. In a case your internal endpoints support H.460 (which is rarely the case) you don’t need Traversal client.
These protocols do not need NAT ALG and require NAT to work in symmetrical mode allowing to create bidirectional pinholes.

H.460.17

This method requires a traversal client to establish a RAS tunnel to a traversal server by sending empty H.225 Transport Protocol Data Unit Packets (TPKT) or RAS rerigestrations to it.
When an internal endpoint wants to reach an external one it send signalling (RAS, H.225 and H.245) to the traversal client (a gatekeeper operating in GKRCS mode) which send them over that long-lived tunnel to the  traversal server. The same tunnel works in the opposite situation when an external endpoint send signalling to the traversal server which use the tunnel to reach
the traversal client. This tunnel needs only one 1720 port to pass through FW.

H.460.18

This one doesn’t use RAS tunnel as H.460.17. Traversal server use special H.323 RAS Service Control Indication to instruct traversal client to open a pinhole in NAT.
After that traversal client kepps the pinhole open by resending RAS RRQ reregistrations, H.225 or H.245 TPKT.
When an internal endpoint wants to reach an external one it send signalling (RAS, H.225 and H.245) to the traversal client, which relays them to traversal server in DMZ.
The traversal client then maintains NAT binding on behalf of the internal endpoint.
When an external endpoint wants to connect to an internal endpoint, the external endpoint sends a setup message to the traversal server, and then creates a RAS SCI packet that requests that the traversal client send an empty H.225 packet out through the NAT to the traversal server to open a reverse pinhole for the incoming setup message. SCI message gives the client all information about destination ports on the server. So this connection is used to transmit signalling from external endpoint to the internal one.

H.460.19

This mechanism allows traversal server to act as a media relay. It provides H.245 fixup to ensure that only routable addresses are transferred to external endpoint.
When an external endpoint wants to send media to internal network it sends media to traversal client, which in turn sends H.245 message to traversal client which instructs it to send empty RTP packet in return, so NAT binding and a pinhole are created and traversal server and client know what ports to use. H.480.19 do the same to RTCP traffic flow.

Additional feature of  H.480.19 is multiplexing, which allows traversal client to use a reduced number of port for RTP. This is done by appending a 4-byte stream number to RTP packet to identify a stream of media.

Assent protocol uses the same principles described above and allows SIP communications as well. The only product I know which implements it is Cisco Expressway
(http://www.cisco.com/c/dam/en/us/td/docs/telepresence/infrastructure/vcs/config_guide/X8-6/Cisco-VCS-Basic-Configuration-Control-with-Expressway-Deployment-Guide-X8-6.pdf)

Cisco Jabber “Share presentation” button is greyed out.

With the newest versions on CUCM and IM&Presence (10.5 and higher) greyed out “Share presentation” button in Cisco Jabber can be caused by a couple of things:
a) “Allow BFCP” checkbox isn’t checked in SIP profile of the CFS (TAB,BOT,TCT) device in CUCM
b) firewall is blocking a connection.
When investigating the latter I decided to discover what is this BFCP and how the presentation is shared.

1) When I make a call from Cisco Jabber to another video-capable endpoint (i.e SX20), a SIP invite is sent with following SDP attributes

Media Description, name and address (m): video 25990 RTP/AVP 126 97
Media Attribute (a): content:main

Media Description, name and address (m): video 26744 RTP/AVP 126 97
Media Attribute (a): content:slides

Media Description, name and address (m): application 5316 UDP/BFCP *
Media Attribute (a): floorctrl:c-s

Attribute with content:main describes our main video stream. The RTP stream will start right after called endpoint answers.
Attribute with content:slides is a presentation stream. This stream will be a usual RTP carrying payload with type of 126 (H264 coded video). It won’t start until we hit “Share presentation” button.
Attribute with application 5316 UDP/BFCP is a description of BFCP protocol. According to https://tools.ietf.org/html/rfc4582 it controls who is holding a shared resource (presentation in our case) and who’s transmitting (to avoid bidirectional presentation sharing).
Import thing here is who is going to be the server in this connection. In my case floorctrl:c-s shows that Jabber is willing to be a server as well as a client.

2) Let’s look at the SIP 200OK with SDP

Media Description, name and address (m): video 16880 RTP/AVP 126
Media Attribute (a): content:main

Media Description, name and address (m): video 16882 RTP/AVP 126
Media Attribute (a): content:slides

Media Description, name and address (m): application 28339 UDP/BFCP *
Media Attribute (a): floorctrl:c-only

First 2 media descriptions are obvious: they are usual answers to offers of the calling party. But in application 28339 UDP/BFCP there is an attribute of floorctrl:c-only.
This shows that called party is going to be a client in BFCP terms. Moreover it will initiate a BFCP connection. If there is a firewall which block UDP port 5316 in direction from endpoint to Jabber, BFCP server in Jabber won’t see an incoming connection and would grey-out the button. This BFCP connection will occur right after SIP 200 Ok and long before you can hit a “Share presentation” button in Cisco Jabber.

3) This only describes a case when you share the presentation during a call.
In addition you can share presentation without making a call from a chat window in Jabber. This is done without BFCP with a different protocol.

Video broadcasting and recording with Cisco part 1 update. CUCM+TCS 6.2

So, Cisco updated Telepresence content server to version 6.2 and provided no release notes. And new documentation leaves much to be desired too (just look at the screenshots at http://www.cisco.com/c/en/us/td/docs/telepresence/tcs/6_2/administration/guide/tcs_6_2/cucm.html – can you guess what’s on them?). I’ve managed to upgrade my TCSs and made them work. 1) There is no upgrade tool presented on Cisco download portal. So I just got tcs_6.2_vm_package.zip, extracted it and ran S6_2_VM.exe on the machine with TCS 6.1. 2) After the install is completed, navigate to Content Server Web interface Management -> Configuration -> Site settings and make SIP setting section looks like that 2015-06-11_1337 (click to enlarge)

Note: 192.168.20.1 is an IP address of Content Server and 192.168.0.1 – CUCM 3) Now it’s time to tune our trunks on CUCM. Navigate to Unified CM Administration -> System -> Security -> SIP Trunk Security Profile and create a new one with these settings:

2015-06-11_1342

4) Now navigate to Unified CM Administration -> Device -> Device Settings -> SIP Profile and create a new one named SIP Trunk profile for TCS. Copying a standart one would do, but don’t forget to tweak it like that:

2015-06-11_1347

5) Final step: go to SIP trunk you’ve created here https://profcollab.wordpress.com/2015/06/04/video-broadcasting-and-recording-with-cisco-part-1-cucmtcs/ and change its SIP Trunk Security Profile and  SIP Profile to the ones you’ve just created. Cisco also recommends to set Rerouting Calling Search Space and Out-Of-Dialog Refer Calling Search Space to something reasonable.

Video broadcasting and recording with Cisco part 3. TCS API

In part 1 of these series we created two aliases 1001 and 1002 and the first one was used for recording. Cisco TCS has it’s own interface for downloading records and provides opportunity to add description to records (recording aliases to be exact) in order to help you identify then later. TCS is build on Windows so you can add it to your domain controller and authenticate users with it. I don’t have one and don’t like the idea of users even browsing TCS interface so here is a simple Python  class with three methods: first for listing all calls on TCS, second is for adding description before recording and last one for obtaining a list of download URLs for recorded streams.

import urllib2 
from suds.client import Client 
from suds.transport.https import HttpAuthenticated 
from suds import WebFault
from datetime import datetime
import xml.etree.ElementTree as ET
TCS_API_HOSTNAME='192.168.0.10'
TCS_API_URL='/tcs'
TCS_API_USERNAME='admin'
TCS_API_PSW='admin' # do not forget to change API password in TCS management interface
TCS_WSDL='http://'+TCS_API_HOSTNAME+TCS_API_URL+'/Helium.wsdl'
TCS_API_PROXY='http://'+TCS_API_HOSTNAME+TCS_API_URL+'/SoapServer.php'
TCS_API_ROOT='http://'+TCS_API_HOSTNAME+TCS_API_URL
class tcs_api_handler(object):     
    def get_current_cf_list(self):    # getting layout of current calls as aliases with their ids        
        passman = urllib2.HTTPPasswordMgrWithDefaultRealm()        
        passman.add_password(None, TCS_API_ROOT, TCS_API_USERNAME, TCS_API_PSW)        
        authhandler = urllib2.HTTPDigestAuthHandler(passman)        
        opener = urllib2.build_opener(authhandler)        
        res = opener.open(TCS_API_ROOT+'/status.xml')        
        response = res.read()        
        res.close()        
        tree = ET.fromstring(response)        
        cf_list={}        
        for call in tree.iter('{http://www.tandberg.no/XML/CUIL/1.0}Call'):            
            cf_id=call.find('{http://www.tandberg.no/XML/CUIL/1.0}ConferenceId').text            
            alias_full=call.find('{http://www.tandberg.no/XML/CUIL/1.0}SIPURI').text            
            cf_list[alias_full.split("@")[0]]=cf_id        
        return cf_list                           
    def prepair_alias(self, alias,description):        
        t = HttpAuthenticated(username=TCS_API_USERNAME, password=TCS_API_PSW)        
        t.handler=urllib2.HTTPDigestAuthHandler(t.pm)        
        t.urlopener = urllib2.build_opener(t.handler)        
        client = Client(TCS_WSDL, location=TCS_API_PROXY, transport=t)                        
        res=client.service.GetRecordingAlias(Alias=alias)        
        res.RecordingDescription=description        
        try:            
            res1=client.service.ModifyRecordingAlias(Alias=alias, Data=res)            
            return res1        
        except WebFault as err:            
            return err            
    def get_donwloadlink_all(self):        
        t = HttpAuthenticated(username=TCS_API_USERNAME, password=TCS_API_PSW)        
        t.handler=urllib2.HTTPDigestAuthHandler(t.pm)        
        t.urlopener = urllib2.build_opener(t.handler)        
        client = Client(TCS_WSDL, location=TCS_API_PROXY, transport=t)                        
        userparams = {'SearchExpression':'','ResultRange':'','DateTime':'','UpdateTime':'','Owner':'','Category':'','Sort':''}        
        res=client.service.GetConferences(**userparams)        
        res1={}        
        for cf in res[0]:            
            time=datetime.fromtimestamp(int(cf['DateTime']))            
            if cf['HasDownloadableMovie']==True:                
                res1[str(cf['ConferenceID'])]= [unicode(cf['Title']).split('$')[0],str(cf['Description']),str(datetime.fromtimestamp(int(cf['DateTime']))), str(cf['DownloadableMovies'][0][0]['URL'])]             
        return res1

So every time recording alias is added to the conference I issue prepair_alias(‘1001′,’Some descriptions’) and when the recording is done and TCS finished transcoding it I can use  get_donwloadlink_all to list all downloadable movies along with their description, timestamp and alias used for recording.

Video broadcasting and recording with Cisco part 2. TCS+Wowza

Last time we created two aliases on Cisco Telepresence Content Server – 1001 for recording and 1002 for live streaming. Up to this step we are able to call these aliases (or add them to conference) to record or broadcast our call or conference.

But TCS can generate RTSP stream and it’s not an obvious task how to integrate this stream into user’s browsers. Again – usually you have 1G link on TCS server and it will allow approximately 500 connections to HD-quality streams.

We are going to use Wowza Streaming Engine to converts RTSP streams to RTMP/HLS/HDS streams that can be served to various flash/html5 players. At the same time we will use Wowza to down-rate streams to lower qualities – not all users have good Internet connection to allow HD streams.

1) Register and download Wowza Streaming Engine from http://www.wowza.com/.
2) Save license key and  WowzaStreamingEngine-4.1.1.deb.bin installation
3) I’m using Ubunty Trusty at the moment. Let’s install Java

# apt-get update
# apt-get upgrade
# apt-get install default-jre
# apt-get install default-jdk

4) Move to the folder with WowzaStreamingEngine-4.1.1.deb.bin and make it executable

# chmod +x WowzaStreamingEngine-4.1.1.deb.bin
#  ./WowzaStreamingEngine-4.1.1.deb.bin

5) During the installation you are prompted to enter license key, create admin credentials and will ask to add itself to autolaunch

6) Now Wowza is ready. Installation path is  /usr/local/WowzaStreamingEngine/.

To start service sudo service WowzaStreamingEngine start
To stop service sudo service WowzaStreamingEngine stop

7) Download WowzaStreamingEngine-Update-4.1.2.zip from  http://www.wowza.com/ and move it to /usr/local/WowzaStreamingEngine/updates/

8) Unpack update file

# apt-get install unzip
# mkdir /usr/local/WowzaStreamingEngine/updates/WowzaStreamingEngine-Update-4.1.2/
# unzip /usr/local/WowzaStreamingEngine/updates/WowzaStreamingEngine-Update-4.1.2.zip –d /usr/local/WowzaStreamingEngine/updates/WowzaStreamingEngine-Update-4.1.2/

9) Stop all Wowza services

# service WowzaStreamingEngine stop
# service WowzaStreamingEngineManager stop

10) Move to folder with update script and launch it

# /usr/local/WowzaStreamingEngine/updates/WowzaStreamingEngine-Update-4.1.2/linux
# chmod +x *.sh
# ./update.sh

11) After update go to  http://<wowzaserver_ip&gt;:8080/  and login with credentials from step 5.

12) Navigate to Applications -> Add Application -> Live (single server or origin) and enter  _defapp_

13) Navigate to Live Applications -> Live. In list below select Incoming Security and make it look like

14) Now navigate to Server -> Publishers -> Add publisher and add new publisher name and password (they will be used lated when configuring Cisco TCS)

15) Edit /usr/local/WowzaStreamingEngine/conf/live/Application.xml

16) Search for Properties and RTP sections – they should look like:

<Properties>
  <Property>
    <Name>sortPackets</Name>
    <Value>true</Value>
    <Type>Boolean</Type>
  </Property>
  <Property>
    <Name>sortBufferSize</Name>
    <Value>500</Value>
    <Type>Integer</Type>
  </Property>
 </Properties>

 <RTP>
  <Authentication>
    <PublishMethod>digest</PublishMethod>
    <PlayMethod>digest</PlayMethod>
  </Authentication>

17) Move to Cisco TCS administration web-interface. Navigate to Management -> Recording Setup -> Media server configurations -> +Add Wowza Media Server for Flash configuration

18) Set the parameters

Name: Wowza 1002
Server address:wowzaserver_ip>
Support live unicast streaming: Yes
User name/Password/Password confirm: see step 14
Use default live URL: Yes
Application directory: live
Static stream name (optional): 1002

19) Hit save. If everything is ok you’ll see:

20) Navigate to Management -> Recording Setup -> Templates -> Live and set

Media server configuration to Wowza 1002

21) Call 1002 from you video codec, navigate to Wowza administration interface Applications -> Live -> Incoming streams, choose 1002, hit Test players in upper right corner, choose appropriate player and you’ll be able to monitor your broadcasting stream.