Zoom and Cisco Room Kit OBTP

Solving a persistent problem between two meeting clients

The Problem

A client recently came to us with an issue they were having with their suite of various models of Cisco Cloud registered Room Kit systems. Zoom and WebEx are both utilized for their meeting clients.  They were able to use the one button to join feature to join WebEx meetings, but the Zoom meetings were prompting for a meeting ID and a passcode. The issue was relayed to our team who began to investigate

What is One Button to Push? (OBTP)

The client has been utilizing a feature in the Room Kit software called One Button to Push (OBTP). It allows users to integrate their calendars with the Room systems and join SIP enabled meetings with a single button. This feature parses the calendar entries looking for meeting information and populates the system with as much of the provided information as possible, limited by the data format and the codec’s interpretation. The full features of OBTP come out when the data contains a properly formatted SIP address. The system will do a few things behind the scenes, then it will send a reply stating that it accepted or declined the invite. If the invite was accepted, then the Touch10 will display the OBTP Join Meeting overlay 5 minutes prior to the start of the meeting. This can also be set to automatically join the meeting 1 minute prior to the start of the meeting, which can be very useful for unmanaged meetings or for those users that need to have a meeting started while they are away from their desk.

Note: There is a lot of backend set up to get this working and as this post is not directly related to how to set up OBTP, I will keep the explanation short and related specifically to the moving parts related to the issue.

OBTP requires a new mail and service account to be generated (O365, exchange, and google). This is the email address that is “owned” by the Room Kit and the calendar of this account is the way in which the system handles reservation management and responding to invites. The Zoom integration requires a secondary and tertiary step of creating a Cisco Room in the Zoom admin portal and installing an .msi on a server  in the local network respectively. This allows the zoom invite to be sent directly to that email address to be interpreted by the system.

Resources: The full guide to installation can be found here: https://support.zoom.us/hc/en-us/articles/115003126346-Using-the-Legacy-Zoom-Connector-for-Cisco

Researching the issue between Zoom and Room Kit OBTP

The first thing our DevOps engineers did was set up a lab in our environment to mimic the issue that our client was having, which meant setting up a Zoom account and modeling our settings from those that our client is using. After being able to replicate the issue and scraping the logs we noticed an SSL error that seemed to be the root cause.

Call disconnected, error shown to be SSL rejection

After chasing that false lead for a while, we determined that there were no issues with the SSL CA that was being used for zoomcrc.com. During our testing for that we found that the voice join function works for Zoom meetings, only the button is broken. When the button is pressed, you get this failed call error in the logs. This provided for a successful joining of the meeting and some obvious differences. Most noticeable is the protocol being used is not SIP, but Spark instead.

Yellow Highlight: Where we identified the Spark Protocol over SIP
Red Arrow: Call 23 showing connecting

Resources: More information on this protocol can be found on page 56 of this PDF of protocols.

This showed that there are different modules being used between the two methods of call and one of those is unable to format that SIP call correctly. This also allowed us to write a macro to successfully dial this number. The next thing we tried was to modify the OBTP overlay so that it was able to format the call the correct way. Unfortunately, the overlay is immutable on the user end, so that idea was scrapped. We briefly toyed with the idea of removing the overlay completely for Zoom meetings and having a custom overlay appear in its stead, but the margin for error was relatively high, the issue could compound during the next software update, and it was a clunky solution. It felt like using a shotgun for a bothersome fly.

Getting in the fix for Zoom and Cisco Room Kit OBTP

We ended up writing a simple listener as the solution to this problem which elegantly stops being called when either Zoom or Cisco fix the issue. This listener looks specifically for calls that are failing for an SSL error to the zoomcrc.com URI, reconstructs the call data correctly, then sends the call. There is a brief ‘Call Failed’ pop-up, then the call connects and does not require a meeting ID or a passcode. While this solution has the small aesthetic negative of the pop-up, it was determined to be the least invasive and most effective mitigation of the issue until these two tech giants decided to play together a bit more nicely.

Have you run into any similar issues? We’d love to hear about it, so feel free to comment below and check our our Zero Trust Philosophy by our own Chris Crotteau.

By: Ben Barnard

Automation With RoomKit

Recently, a customer came to us with an interesting problem with their Room Kits… 

The Challenge

Our client has many Cisco Room Kit installations ranging from large training areas on the Room Kit Pro, to some smaller conference rooms and huddle spaces. Most multi-display video systems have two or more same-sized televisions, generally right next to one another. One screen will show the presentation, the other screen will show the active, remote speaker. The smaller spaces didn’t have enough wall real estate to support two large televisions like the training areas on the Room Kit Pro did. 

Instead, a large primary display along with a smaller secondary display, was chosen:

When the displays are both the same size and right next to one another, it doesn’t usually matter which one is showing the presentation and showing the speaker.

This looked good in visual concept; however, the challenge came in utilizing the larger display for the most prominent media. When there was no presentation to show it made sense to have the speaker on the largest screen, but if the speaker had a presentation to pull up then they needed the larger screen to display the presentation content. 

As illustrated in the photo, the active speaker (screen greyed for customer anonymity) remained on the larger display, and the presentation showed on the smaller display. Shy of moving the HDMI cables by hand every time a presentation started, there was no way to accomplish this on RoomOS.  

Moreover, it was desired that it moved back when a presentation stopped. For example:

Circumstance: Speaker Talking, No presentation

Desired Outcome: Larger TV shows Speaker; Smaller TV Blank

Circumstance: Speaker Talking, with presentation

Desired Outcome: Smaller TV shows Speaker; Larger TV shows presentation

Circumstance: Speaker Talking, was presenting, but stopped presenting

Desired Outcome: Speaker swaps back to larger TV; smaller TV becomes blank

Crossconnect’s challenge was to develop a way to ensure the presentation always ended up on the larger display with minimal user intervention. This presented a variety of complexities since our client needed RoomOS to do this regardless if the presentation was shown via Webex, HDMI input, or Cisco Proximity (https://proximity.cisco.com/). Another added complexity we faced was “How would a Room Kit even know how big a display is?”

How did we accomplish this?

Presented with the complex requirements of our client we knew some custom work was needed. Over the course of two weeks, we developed our own RoomOS script that:

– Tracked the native resolution of the TV as a way to determine TV size

– Ensured if only one input (speaker) was present that it ended up the larger TV

– Triggered logic when a presentation started to ensure the presentation always ended up on the larger TV.

– Triggered logic that when a presentation stopped to ensure that the speaker moved back to the larger TV.

– All of this was accomplished without any user input, it “just works”. In case the user wanted to manually control it, Crossconnect built a button to allow manual display swapping, but this is purely optional

– Was extensible into 3+ display units for future use.

We had an “aha” moment on how to keep the presentation on the larger screen while working on the ‘Call’ and ‘Video Output Connector’ objects within the codecs xAPI interface. We used this in order to determine information about the current monitors as well as to get the information required to asynchronously monitor the device for the following: 

(1) Call status

(2) Call properties (is this a video call?)

(3) Content Sharing

This allowed us to determine which screen received the presentation at any given status change during the call, while monitoring for changes in real time. Initially, we wrote a program that walked the available xAPI endpoints both inside and outside of calls to determine which endpoints needed to be referenced for accuracy. 

The first portion of the program runs when the codec starts up. This initially finds a few key characteristics of the output connectors and determines which one will be the main display monitor.

Here is what that looks like: 

function getResolution(data) {
  for (var set in data) {
    if (data[set].hasOwnProperty("Resolution")) {
      var pushMe = data[set].Resolution.Width + "x" + data[set].Resolution.Height;
  console.log("Video resolutions have been found: " + resolutions.toString().replace(",", ", "));
  for (i = 0; i < resolutions.length; i++) {
    if (resolutions[i].split("x")[0] > largestScreen.split("x")[0]) {
      largestScreen = resolutions[i];
    else if (resolutions[i] == largestScreen) {
      console.log("Multiple screens have been found: system will choose the first one found.");
  for (i = 0; i < resolutions.length; i++) {
    if (resolutions[i] == largestScreen) {
      screenChoice = screenIDs[i];
  console.log("Largest screen determined to be screen ID: " + screenChoice + "(" + largestScreen + ")");

After this has been determined it just listens for either:

A) a change in output connectors at which point it would recalculate the metrics mentioned above, or 

B) a call starts, at which point the real meat of the program does its job. 

When a call connects it checks to see if it is a call with video capabilities and if it is, it begins the smart screen presentation features. 

async function getVideoCall() {
  let isVideo = false;
  if (await (xapi.status.get('Call'))) {
    await (xapi.status.get("MediaChannels Call")).then(data => {
      let index, channel = null;
      for (index = 0; index < data[0].Channel.length; index++) {
        channel = data[0].Channel[index];
        if (channel.Direction == 'Incoming' &&
            channel.Type == 'Video' && 
            channel.Video.ChannelRole == 'Main' &&
            channel.Video.Protocol != 'Off') {
            isVideo = true
  return isVideo

It will initially set the larger screen to be the main display monitor and sets the smaller screen(s) as the secondary monitor(s). 

As soon as the call listener recognizes that a screen share has been sent locally (through HDMI or through proximity) or remotely (through any SIP dialed device) it switches the screen so that the larger monitor is presenting the screen share and the other screens have the call audience. As soon as the screen share has ended, the larger screen takes over the main portion of the view layout that has been chosen by the end user for the meeting. 

We also gave a manual option to swap the screens with a button if the end user would like to have them be different from the programmatically decided screen. This automatically jumps right back into the smart monitor decisions once the presentation has concluded.  

Once we had the concept working it was time to show our clients. They were absolutely thrilled with how this project turned out. During the proof of concept meeting our client stated their intentions to expand implementation. This is just an example of the way Crossconnect approaches each client’s needs as their own unique situation while creatively attacking the challenge. If you’re facing technology challenges without a clear resolution, then reach out and let our team of engineers help you game plan a solution that works for your company. 

Jeff Kronlage CCIE# 46110 -CEO of Crossconnect