Vista ICM Panel Development

From LinuxMCE
Revision as of 20:30, 26 August 2009 by Ray N (Talk | contribs)

Jump to: navigation, search

This page details the development of the Vista ICM device driver for compatible security panels from Honeywell/Ademco. It intends to show the overview of the development process for the interested developers who wish to create new device support for LinuxMCE.

Initial Research

Initially, you need any specifications that you can retrieve to tell about the device you wish to implement. These can be gotten from a variety of sources, including:

  • Manufacturer's website
  • Various google searches on the web (try the following search words: protocol specification, rs-232, technical reference, and custom installer specification along with the name and model of your intended device.)
  • Existing literature that you may have, check the appendices.

In our case, the following web link proved especially useful:

Consideration: C++ or Generic Serial Device ?

This link provided a reverse engineered protocol specification of a device that provides:

  • 1 TCP port for sending commands using the HTTP protocol
  • 1 UDP port for retrieving panel status information, that is sent to the global broadcast address of the network (INADDR_ANY)

There were two other ports exposed, but were deemed not to be useful for the implementation of this device.

This brings up two very important points:

Because we failed both criteria, the device was written as a C++ device.

Installation of a basic development environment

A basic development environment was set up on the target machine. Since we were not dependent on sql2cpp changes common in other plugins such as the Media Plugin, we chose a very quick and simple method for setting up a development environment that entailed:

  • Installing SVN
  • Getting the SVN checkout.
  • Installing enough of the builder to get the build dependencies needed.
  • Installing DCEGen
  • Installing Sql2cpp

NOTE: This method is ONLY meant for device driver development of a single device! For anything more complex, such as plugin development, or working on existing code, YOU SHOULD INSTALL A FULL BUILDER, AND HAVE IT CREATE PACKAGES FOR YOU.

Installing SVN

SVN can be installed using apt.

apt-get install subversion

Getting the SVN Checkout

At the time of this writing, the SVN checkout of the latest dev code can be retrieved here.

sudo -i
mkdir /home/src
cd /home/src
svn co

Wait for the checkout to complete.

Installing enough of the builder to get the necessary build dependencies

You can then install enough of the builder so that the necessary packages to build everything is installed.

cd /home/src/LinuxMCE-0810/src/Ubuntu_Helpers_NoHardcode
cd /usr/local/lmce-build

Let this complete. Lots of packages need to be installed, and this will take a while.

Installing DCEGen

Install DCEGen by doing the command:

apt-get install pluto-dcegen

Installing Sql2cpp

Install SQL2cpp by doing the command:

apt-get install pluto-sql2cpp

You now have everything needed to do device driver development.

Device Template

Device Templates are at the heart of LinuxMCE. They provide needed information so that the system can properly manage a device, such as:

  • The Name of the device
  • The Category of device (a TV, a Security Panel Interface, a Media Player, etc.)
  • Device Data the device may need to function
  • Commands the device may wish to respond to
  • Events the device may wish to emit for other devices to respond to.
  • Information for Plug and Play such as a MAC address range, or a Vendor/Model pair for PCI or USB

We used the Apex Destiny 6100 as the basis for our device template, opening its window via Advanced > Configuration > Device Templates in the Web Admin

A quick note before making the new template: Update your DCE repository via SqlCVS!

Before we make a new template, we use the Advanced > sqlCVS > update menu to update all the tables in the DCE repository. This is to make sure we are up to date before we make a new template. Please do this.

Important notes on the device template

We then made a new device template, and told the system that it was to be a device implemented via C++.

Of course, we called it the VistaICM, and it is a Security Interface, so the category is set appropriately. We also specified that the Device is controlled by Category Computers - CORE So that the system understands that this device will run on the core. This was done because the device is a network device that will have its device driver run on the core, and will be an immediate child of the core in terms of where it is in the device tree.

We then specify that the device is IP Based

Device Data

Any device may need any number of parameters that you can change, or that other things can change over time. This is referred to as Device Data and in our case, we're not needing anything other than a parameter to specify Zone maps, so we select Zones from the Add Parameter list, and select Add.


Any device should have a number of commands that it can respond to. Some suggested commands may be presented if your device belongs to a certain category. For example, a Security Panel has commands for setting house modes, getting the list of sensors, and reporting child devices. This seems applicable for us, so we check that command group. Spend some time looking through the command groups using the Edit Commands button to look at the commands present to see if they apply to you.

We simply choose security panel.


Here, you can specify what events that the device EMITS. This does not mean that the device recieves those events, it merely specifies what events the device can send. For a C++ device, it amounts to creating a series of convienience functions beginning with EVENT_, such as EVENT_Sensor_Tripped(true), etc. that you can call from the program code. As per the Apex 6100 template, I added events for the following:

  • Alarm Panel Mode Change
  • Fire Alarm
  • Sensor Tripped

If I knew I could have introspected child devices, I would have added an event for reporting a child device.

Plug and Play

Because this is a network device, It can be detected via plug and play. In our case, we look for a MAC address range. The simplest way to get this MAC address range is to use a network tool such as nmap running as root to get the MAC address of the device. You can then use the returned information to get a MAC address range from this site:

For simplicity, we used the entire MAC address range from AA:BB:CC:00:00:00 to AA:BB:CC:FF:FF:FF. However the entries for the MAC range From and To do not use the hex:colon notation, they are represented in decimal. Use the convert_mac utility to get the decimal numbers, for example:

linuxmce@dcerouter:/home/src/LinuxMCE-0710/src/Security_Plugin$ /usr/pluto/bin/convert_mac 00:19:45:00:00:00
linuxmce@dcerouter:/home/src/LinuxMCE-0710/src/Security_Plugin$ /usr/pluto/bin/convert_mac 00:19:45:FF:FF:FF

Using those ranges in the from and to are sufficient enough to be able to detect our device.

I put Vista ICM in the comment field and pressed Add.

We don't have any related devices, but if we needed another device template to function properly (such as a streamer device to run on the core, or a media streamer plugin, or any children devices that we know we would need), we could specify them here, along with any parameters needed in the form of devicedata#|paramvalue|devicedata#|paramvalue

We can then press Save, because the device template is finished for now. We will come back later and add the package definition once it's complete.

Code Development

Now that the device template is complete, we can run DCEGen to generate the code stubs, sql2cpp to generate any needed device constants, and start implementing the code.

Running DCEGen

DCEgen needs to run from the DCEGen source directory. It should only need one parameter, the # of your new device template that you created. If you do not have it readily available, go back to the web admin and get the device template #.

cd /home/src/LinuxMCE-0810/src/DCEGen
/usr/pluto/bin/DCEGen -d xxxx

your new device template will be present in the parent directory.

Running Sql2cpp

Now, you will need to run sql2cpp to generate needed defines that DCEGen created within your new code.

cd /home/src/LinuxMCE-0810/src/sql2cpp

The defines will be generated. and

Before continuing, you need to create the following tools and place them in /usr/local/bin

### Use this script to prepare the build for dev work.
### NOTE: Be sure to run unprep to revert the prepped
### makefiles!

## Back up the original unprepped makefiles.
for i in $(find . -name Makefile)
  echo Backing up $i to $i.unprep
  cp $i $i.unprep 

echo Prepping sources... 

find . -iname Makefile -exec sed -e 's/<-mkr_t_compile_defines->/-DKDE_LMCE -DDEBUG -DTHREAD_LOG -DLOG_ALL_QUERIES -I\/opt\/libxine1-pluto\/include -I\/opt\/libsdl1.2-1.2.7+1.2.8cvs20041007\/include -I\/opt\/libsdl1.2-1.2.7+1.2.8cvs20041007\/include\/SD/' -i '{}' \;
find . -iname Makefile -exec sed -e 's/<-mkr_t_compile_libs->/-L\/opt\/libxine1-pluto\/lib -L\/opt\/libsdl1.2-1.2.7+1.2.8cvs20041007\/lib/' -i '{}' \;

### this script undoes all of the prepping steps done by by
### simply moving the old prep files back into place.

for i in $(find . -name Makefile.unprep)

echo Undoing Prep for $i

mv $i `dirname $i`/Makefile  


Implementing code

You can then use the script to prep the code appropriately, so that you can build it. In the future, this process will be removed once we have removed the old Pluto MakeRelease tags.

When you are done hacking on code and are ready to make a patch, you must run before making the patch!

cd /home/src/LinuxMCE-0810/src/VistaICM2

Basic hacking process

Once you have made changes to the source, you can use make bin (for a standard DCE device), or make so (for a DCE plugin) to create the necessary binary. make clean will delete the object files, etc.

In order to test the device, you'll need to go into the Web Admin, and create an instance of the device. Note its device #. Once you have this, you can start the device from its directory by typing:

./VistaICM2 -d 105

where -d xxx is the device # assigned by the system.

Any time the device needs to be reloaded, it will stop, and you will need to reload it again. This is because the device is not being managed by

Running the device in gdb

To debug runtime errors, gdb can be used, I run the devices as such:

gdb --args ./VistaICM2 -d 105

and use gdb as normal.

Some Basic Notes on the code design

The code skeleton generated by DCEGen provides the bare skeleton that you will need to create the device. It provides some basic examples on calling DCE to send commands, and events, in various permutations, as well as how to access device data using the convienience accessors provided. ndo, to make the device function.

I chose a design like the following:

  • Main Thread, runs the DCE device and its runloop. This handles the commands, and sending events etc to the system
  • the ccp Thread, for dealing with the CCP port, it has its own runloop. I connect to the instance of the main running class to do method calls from this outside thread, as well as setting some basic states (is the ccp thread running or not, etc.)


Sending it all In

Sending in the Patch

Creating the Package Definition

Checking in the sqlCVS changes anonymously

You should be done at this point. The driver will now be built as part of our release process, and will become part of the autobuilds, so that you can either do your own builder as described in Building LinuxMCE 0810 or you can wait for the build process to produce packages for your new driver.