S4B 2015 certificate when connecting to CMS part 2

If, when attempting to establish a call from S4B to CMS, the call fails and all you can find in the logs is;

INFO : SIP trace: connection xxx: read failure, code 104
INFO : SIP trace: connection xxx: shutting down...

…it is due to the CN of the certificate on CMS not matching the CsTrustedApplicationPool Identity. Update that on the S4B-side (remove and re-create) or replace the CMS certificate CN.


S4B 2015 certificate when connecting to CMS

Microsoft documentation points to using the Webserver (default) certificate template for the frontend pool. This WILL NOT WORK when configuring a trusted SIP-trunk to CMS.

This is poorly documented by both Microsoft and Cisco, but the trick is to use a template that contains Client Authentication in addition to Server Authentication as Extended Key Usage (Application Policy in Microsoft CA).

The lack of Client Authentication in the certificate will show in the CMS log as handshake error 336105606.

UCCX Finesse IE Compatibility

Just noticed after an upgrade from UCCX 10.6 to 11.6 that IE11-settings can become troublesome.

Login and call-handling actually worked as expected, but it was impossible to load CUIC-based gadgets.

The resolution:

  • Document mode must be set to Edge.
  • Compatibility mode must be set to Off.
  • If Enterprise Mode is running, the URL(s) should be set to apply Desktop profile.
  • Also, if running Chrome instead, remember that recent versions require the CN to be included as a SAN as well in the certificate to avoid warnings.

Modify INVITE (to CMS Space / CMS Space naming)

I have spent serious time considering how I want to address my spaces within CMS. I’m personally not to happy with the idea to utilize prefix/suffix on the userpart, such as cmr-username, username.vmr – whatever name you want to use, or where you place it. My preferred logic there would be to have the CMS-spaces within a specific subdomain, so – to call a user directly you would dial username@domain.tld and to dial the space of the user you would dial username@meet.domain.tld.

Attempting to apply this logic does however introduce a few issues.

If the username should be used to provision the space – guess what, it will not synchronize that user. That causes a conflict with the adressing of the actual user if you were using the MeetingApp. Reachibility for the MeetingApp is way beyond the scope of this post, we are using devices and/or Jabber and will just use the spaces within CMS.

So, to manage this, I do need to provision the space using a prefix (or suffix), such as cmr-username and rewrite the invite on the way. Where should I do that? It would be very easily done in the VCS, a bit more tricky on the CUCM side – but still doable.

I will not argue that this script is perfect at the moment, but it is a start and can surely be developed further down the road. I’ve also argued heavily with myself if the To-header also should be updated, but it seems to work just fine with only updating the INVITE, so I’m happy with that for now.

The script;

M = {}

local cmrDomain = "meet.domain.tld" 

function M.outbound_INVITE(msg)
  local method, ruri, ver = msg:getRequestLine()
  if string.find(ruri, cmrDomain) then
    startTo_str = string.find(ruri, "sip:")
    endTo_str = string.find(ruri, "@", startTo_str+1)
    toUserPart_str = string.sub(ruri, startTo_str+4, endTo_str-1)
    if not string.sub(toUserPart_str, 0,3):match("cmr-") then
      changedToUserPart_str = "cmr-" .. toUserPart_str
      changedRuri_str = string.gsub(ruri, toUserPart_str, changedToUserPart_str)

return M

Worth mentioning about the script is the parameter for cmrDomain, without a check to make sure we are only applying this script for the actual domain we’re planning to use here – it would for sure break CUCM integration with regards to AdHoc conferences. (CUCM will create a temporary space, using id@fqdn – we don’t want to interfere there). Also, if you use another naming-convention then cmr-…., pay attention to line 11/12 and modify the code accordingly. There is also a check if cmr- is already present, if so we do not want to add it again.

Also, keep in mind – if you create dedicated spaces, configure them within CMS with the prefix of cmr-, or apply logic to exclude them from the script as well. 🙂

Unable to add host to Nexus1K/DVS?

I ran into the issue when trying to add a new host to a Nexus1K that the host selection screen was just empty. This was fairly well documented by VMware in KB2039046, even though the SQL syntax was not really.. ..perfect?! :).

For ESXi 6.x, run the following SQL query against your VC DB (replacing dvSwitch below);

DECLARE @dvs_name varchar(32);
DECLARE @dvs_id int;
SET @dvs_name = 'dvSwitch';

Restart the vCenter service, and voilà!

Modify Diversion history

I ran into a challenge with a customer after upgrade from CUCM 8.6 to 11.0 and Mitel CMG from 7.5 to 8.2.

They have a flow where a caller calls a CTI-Port which during opening hours has a CFUR to a hunt-pilot. The hunt-pilot has a CFNA/CFB to the CMG IVR.

The diversion history becomes quite interesting here;

Diversion: <sip:huntpilotno@10.x.y.z>;reason=no-answer;privacy=off;screen=yes,<sip:ctiportno@10.x.y.z>;reason=out-of-service;privacy=off;screen=yes

The issue that arises is that we will look at the first redirecting number (ctiportno), which – technically speaking, actually has a very correct reason (out-of-service). So, to be able to determine the cause for this forward after hitting the hunt-pilot, we would have to look at the last redirecting information – but, that is another number, and we will run into issues matching that to the subscriber in CMG.

In order to use the last redirecting cause, but still rely on the first redirecting number, I applied a LUA-script to the trunk.

M = {}
function M.outbound_INVITE(msg)
    local diversion= msg:getHeader("Diversion")
    if string.find(diversion, "reason=") then
      startDivCause_str = string.find(diversion, "reason=")
      endDivCause_str = string.find(diversion, ";", startDivCause_str+1)
      divCause_str = string.sub(diversion, startDivCause_str, endDivCause_str)
      changedDivCause_str = string.gsub(diversion, "reason=out%-of%-service;", divCause_str)
      msg:modifyHeader("Diversion", changedDivCause_str)

return M

This script will look if there is a reason within the Diversion and if so, search for the first occurrence (last redirecting pty) and then make a search and replace for reason=out-of-service with whatever the first reason is.

The diversion header in a call which does not get answered by the hunt will now look like this when hitting the CMG;

Diversion: <sip:huntpilotno@10.x.y.z>;reason=no-answer;privacy=off;screen=yes,<sip:ctiportno@10.x.y.z>;reason=no-answer;privacy=off;screen=yes

Some helpful resources;

FCAL for BR-825

Note to self: To enable FCAL for BR825 from an ESXi-host, download (from QLogic), transfer to ESXi-host and install the BCU ESX CLI-plugin;

esxcli software vib install --no-sig-check --maintenance-mode -d /path/to/bcu_esxXX_X.X.X.X.zip

Run the following commands;

/opt/brocade/bin/bcu port --topology 1/0 loop
/opt/brocade/bin/bcu port --topology 1/1 loop
/opt/brocade/bin/bcu port --disable 1/0
/opt/brocade/bin/bcu port --disable 1/1
/opt/brocade/bin/bcu port --enable 1/0
/opt/brocade/bin/bcu port --enable 1/1

To update firmware, run the following command;

/opt/brocade/bin/bcu boot --update /path/to/brocade_adapter_boot_fw_vX-X-X-X.tar.gz -a