In this series of posts, we’ll develop a basic module for controlling Cisco Room Kit devices. It can be used in SIMPL Windows or SIMPL# Pro programs. It won’t be as exhaustive as the official module available from the Application Market, but it will be enough to handle most video conferencing tasks.
Create a new SIMPL# Library
Create a new SIMPL# Library in Visual Studio 2008. I’ve named mine CiscoRoomKit:

We’ll start out by adding a new class named Device to our project:

You can delete the Class1.cs file from our project. Your Solution Explorer should look like this:

Now open up Device.cs and enter in this skeleton code to get us up and running:
using System;
using Crestron.SimplSharp;
namespace CiscoRoomKit
{
public class Device
{
public string Host { get; set; }
public string User { get; set; }
public string Password { get; set; }
public Device()
{
}
public void Connect()
{
}
public void Disconnect()
{
}
}
}
This class will handle connecting and disconnecting from a network device. For that, it needs to know the Host
, User
, and Password
to connect. Remember that we need a default constructor to work with SIMPL+, so we can’t pass any of this info in when the object is created.
We’ll keep things simple for now and only support SSH connections. We’ll add a few using
statements and an SSH client to our class:
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharp.Ssh.Common;
namespace CiscoRoomKit
{
public class Device
{
private SshClient _ssh;
public string Host { get; set; }
public string User { get; set; }
public string Password { get; set; }
public Device()
{
}
public void Connect()
{
// Handle interactive authentication (typing in password)
var auth = new KeyboardInteractiveAuthenticationMethod(User);
auth.AuthenticationPrompt += HandleAuthentication;
// Create connection info
var conn = new ConnectionInfo(Host, User, auth);
// Connect SSH session
_ssh = new SshClient(conn);
_ssh.ErrorOccurred += HandleError;
_ssh.Connect();
}
public void Disconnect()
{
if (_ssh != null)
{
// Disconnect and dispose of SSH session
_ssh.Disconnect();
_ssh.Dispose();
_ssh = null;
}
}
private void HandleAuthentication(object sender,
AuthenticationPromptEventArgs args)
{
}
private void HandleError(object sender,
ExceptionEventArgs args)
{
}
}
}
We register an AuthenticationPromptEventHandler named HandleAuthentication. We also register an ErrorOccurredEventHandler named HandleError. These methods are private to our class. Inside our HandleAuthentication event handler, we really just need to look for a password prompt and respond to it:
private void HandleAuthentication(object sender,
AuthenticationPromptEventArgs args)
{
foreach (var prompt in args.Prompts)
{
// Look for password prompt and respond
if (prompt.Request.Contains("Password:"))
{
prompt.Response = Password;
}
}
}
But how will we notify SIMPL+ once we’ve actually connected? Or what happens if we accidentally disconnect? We need to create a few events to notify SIMPL+ when these things happen:
public class Device
{
private SshClient _ssh;
public string Host { get; set; }
public string User { get; set; }
public string Password { get; set; }
public event EventHandler OnConnect;
public event EventHandler OnDisconnect;
public Device()
{
Update Connect to call OnConnect:
public void Connect()
{
// Handle interactive authentication (typing in password)
var auth = new KeyboardInteractiveAuthenticationMethod(User);
auth.AuthenticationPrompt += HandleAuthentication;
// Create connection info
var conn = new ConnectionInfo(Host, User, auth);
// Connect SSH session
_ssh = new SshClient(conn);
_ssh.ErrorOccurred += HandleError;
_ssh.Connect();
if (OnConnect != null)
{
OnConnect(this, new EventArgs());
}
}
Update Disconnect to call OnDisconnect:
public void Disconnect()
{
if (_ssh != null)
{
// Disconnect and dispose of SSH session
_ssh.Disconnect();
_ssh.Dispose();
_ssh = null;
if (OnDisconnect != null)
{
OnDisconnect(this, new EventArgs());
}
}
}
And update HandleError to see if we disconnected:
private void HandleError(object sender,
ExceptionEventArgs args)
{
if (!_ssh.IsConnected)
{
if (OnDisconnect != null)
{
OnDisconnect(this, new EventArgs());
}
}
}
Build the library and now let’s switch over to SIMPL+ to write the wrapper we can use in our programs.
Create a SIMPL+ wrapper
Copy the CiscoRoomKit.clz file to a new directory where we can work on the SIMPL pieces. In the SIMPL+ editor, create a new module named Cisco Codec Wrapper.usp:
// --- Compiler Directives ---
#DEFAULT_VOLATILE
#ENABLE_STACK_CHECKING
#ENABLE_TRACE
#DEFINE_CONSTANT MAX_NAME_LEN 50
#USER_SIMPLSHARP_LIBRARY "CiscoRoomKit"
// --- Inputs ---
DIGITAL_INPUT Connect;
// --- Outputs ---
DIGITAL_OUTPUT Connect_Fb;
// --- Parameters ---
STRING_PARAMETER Host[MAX_NAME_LEN];
STRING_PARAMETER User[MAX_NAME_LEN];
STRING_PARAMETER Password[MAX_NAME_LEN];
// --- Global Variables ---
Device Codec;
// --- Events ---
PUSH Connect
{
Codec.Connect();
}
RELEASE Connect
{
Codec.Disconnect();
}
EVENTHANDLER Codec_OnConnect (Device sender, EventArgs args)
{
Connect_Fb = 1;
}
EVENTHANDLER Codec_OnDisconnect (Device sender, EventArgs args)
{
Connect_Fb = 0;
}
// --- Main ---
Function Main()
{
Codec.Host = Host;
Codec.User = User;
Codec.Password = Password;
RegisterEvent(Codec, OnConnect, Codec_OnConnect);
RegisterEvent(Codec, OnDisconnect, Codec_OnDisconnect);
WaitForInitializationComplete();
}
We’ll pass the connection information in using the parameters: Host
, User
, and Password
. The first thing we want to do in Main is assign these parameters to our Codec
device. Then we’ll wait for a push on Connect
to trigger our Connect method. When Connect
is released, we’ll call our Disconnect method.
Our event handlers for Codec_OnConnect and Codec_OnDisconnect handle updating Connect_Fb
to our SIMPL program.
Save and compile this module.
The SIMPL Windows Demo
Now you need to create a new SIMPL Windows program to demo the module. Save this program in the same directory where you saved your SIMPL+ wrapper. Drop the wrapper module into your program and fill in the connection information:

Save and compile this program and load to your processor (in my case a CP3), then fire up SIMPL Debugger to watch what happens. If you have an actual device to connect to, you should see:

That’s it for now. In the next part we’ll look at sending commands to the codec and receiving responses. Source code is available on GitHub here: https://github.com/kielthecoder/SoupToNutsModules/tree/main
Thanks for reading!