Managing Remote Devices with Odyssey Athena and XML Web Service

 

Christian Forsberg
businessanyplace.net

August 2005

Applies to:
   Windows Mobile 2003 software for Pocket PCs
   Visual Studio .NET 2003
   .NET Framework version 1.1

Summary: Learn how you can manage Pocket PCs with XML Web Services by using Athena from Odyssey Software. After a general discussion about device management and an introduction to Athena, a sample application user interface with code written in Visual C# is described. (33 printed pages)

Odyssey Software CFCOM enables transparent access to controls such as the Windows Media Player, objects such as the Pocket Outlook Object Model and ADOCE, and virtually any third-party COM or ActiveX component. CFCOM can be licensed from Odyssey Software, although the code sample in this article will work with the license key found in the source code.

Download cfcom.exe from the Microsoft Download Center.

Download Odyssey Software Athena.

Download Managing Remote Devices Using XML Web Services.msi from the Microsoft Download Center.

Contents

Introduction
Device Management in the Enterprise
Athena
Device Manager Sample
Code Walkthrough
Conclusion

Introduction

As the number of devices increases in an enterprise, managing these devices becomes a very difficult manual task. Soon you need an automated solution that can assist in tracking the devices. Companies like Extended Systems, Intellisync, and SOTI provide solutions that offer sophisticated device management functionality. These companies usually offer ready-made solutions for device management with solid functionality. Most of these solutions are proprietary and have a fixed user interface (UI) for management that is not easily customized, which may not be a problem for many enterprises that need only standard functionality.

However, given that many mobile solutions have been deployed and maintained over the last couple of years, it is obvious that the need for managing the devices varies from enterprise to enterprise — and even varies for different mobile solutions within the same enterprise. Therefore, the ability to write applications that manage the devices in a customized way is most welcome.

Odyssey Software's product, Athena, offers such ability. Athena offers device management functionality that is made available by using common standards like HTTP, XML, and SOAP (XML Web Services). The software that you install on the device includes a Web server that provides device management functionality through a number of plug-ins (extensions) in an open architecture. The functionality is offered as customizable Web pages that you can access from any browser. More interestingly, the same functionality is also offered as XML Web Services to be used from any application that can call XML Web Services. This feature is also very interesting from a security point –of view because all device management can be done with standard HTTP (over port 80), which will pass through most firewalls. The product is truly an open platform to build upon, and many more plug-ins are being developed for it. It may be possible in the future for customers and third-parties to develop their own plug-ins. You can find a more detailed description of Athena in the section "Athena."

Device Management in the Enterprise

Device management is a very broad term, but the primary goal is to maintain consistency among the managed devices and to provide support to the device users. Enterprise-wide device management includes the following requirements:

  • Software deployment and management
  • Device discovery of installed, configured, and operational hardware and software
  • Application configuration
  • Software, license, and hardware asset tracking
  • Backup and restore user data
  • Document and file transfer
  • File management
  • Help Desk support, user notification, and troubleshooting
  • Remote device supervision, diagnostics, and troubleshooting

Software deployment is about making the administrative process of installing applications on the devices as efficient as possible. You first distribute the setup files of the applications, and then you initiate the installation. Management of installed software includes the ability to capture information about which applications are installed, perform updates, and also to remove applications from the device. Configuring applications may be as simple as modifying the device registry, but it may also include the distribution of configuration (XML provisioning) files for system or application setup. Related to application configuration is the general asset tracking of both hardware and software (and software licenses).

Backup covers the needs for capturing important information from the device and transferring it to a secure, central location (and maybe removing it from the device as soon as possible to minimize the risk of unauthorized access). The ability to copy any file from the device to a server is critical, and, equally important, is the ability to rapidly restore files when an accident happens. (For example, users have forgotten to keep the battery charged and have lost everything on the Pocket PC because it was hard reset).

The ability to simply transfer files to and from the device is a core feature that can be used in many different ways as is the ability to remotely manipulate the device file system. This functionality is very important because many problems can be fixed by manipulating the device files (and folders).

The need to be truly interactive with the users and their devices is obvious for most help desk personnel. Communicating with the user in an efficient way is the key to successful user support. Such communication includes the easy capture of device information (memory usage, running processes), but also information such as what is actually on the device screen at a certain time. The ability to interact directly with the device from a remote location explicitly demonstrating device or application features is probably the most efficient way to show users how something should be done on the device.

The list can probably be made longer, but the previous requirements show how broad the scope is for device management. These requirements can be translated into the following functionalities:

  • Uploading to and downloading files from the device
  • Installing and uninstalling applications and components
  • Copying, moving, and deleting files locally on the device
  • Remotely controlling the device (screen capture, start/stop processes)
  • Sending messages to the device for display to device users
  • Tracking and monitoring the device
  • Capturing all sorts of device statistics (through both pull and push methods)

In an enterprise setting, the device management probably needs to be seen in the broader perspective of asset management of the entire enterprise. Many assets may need to be managed, and some solutions may be in place to manage some or all of those assets. Therefore, there is often a need to integrate those asset management systems. A typical solution for monitoring an IT infrastructure is to use Microsoft Operations Manager (MOM). Because MOM is XML Web Service–enabled (with its MOM Connector Framework), it can use Athena for capturing information about devices, and that information can be consolidated with information about other assets. You can then use the consolidated information for analysis and reports.

The example of integrating MOM and Athena indicates that XML Web Services for device management and provisioning is gaining popularity. When standards like WS-Management are adopted, Athena will be well positioned to support its specifications and interfaces. This vision of a unified management interface (WS-Management), will take customized device management, outlined in the rest of this article, a step further with the ability to create more powerful tools that use these standard interfaces.

However, the previously listed functionalities and the following discussion can be summarized into three common device management scenarios:

  • Application management
  • Remote control
  • Device information

The most common use of a device management application is to send new software to the device and install it. These actions require having the three first functionalities from the previous list completed and involve the process of first uploading a setup file (.cab) to the device and then running that setup file. To install the software, you will probably need some functionality to discover what applications (and versions) are currently installed on the device, and also some general file management functionality, such as copy, move, and delete.

Another major management scenario is to monitor which devices are available and, when needed, to be able to assist the device users. A request for assistance may be initiated by the user contacting a help desk or by the help desk sending a message to the user. The ability to see what is on the user's screen and even to remotely interact with the device is very powerful in any remote assistance (help desk) scenario. It becomes even more powerful when combined with the ability to capture device information and even start and stop running applications.

The last major management scenario is probably the ability to capture and collect information about the device and its use. This information includes both static information like device type and operating system and more dynamic information such as application usage, file information, memory usage, and battery performance. The capture should be initiated either by the server (with a so called "server pull") or by the device (with a so called "device push"), and it should be possible to initiate the capture on demand (manually) or on a defined schedule. The information that was captured could be very useful for creating statistics that can improve the use of devices and their software.

Before looking at a sample that implements functionality for the previously described scenarios, Athena needs to be described.

Athena

Athena runs on a Windows Mobile–based device and exposes several device management interfaces that can be accessed by using standard Internet protocols. Athena can be called from both central server locations and from other devices. Figure 1 shows the key components of the Athena architecture.

Click here for larger image

Figure 1. Athena architecture. Click the thumbnail for a larger image.

The Web Server serves both Web pages and XML Web Service calls. Security features protect the device from unauthorized calls. The plug-ins is hosted by the Athena Service Host. Each plug-in is implemented as a DLL (dynamic-link library) that runs in the process of the Athena executable (Service Host).

Athena provides many options for configuring security with regard to access control and confidentiality. Access control can be defined for authentication (user validation), authorization (access rights), and device access (which IP addresses are allowed or denied access). Support for Secure Sockets Layer (SSL), which is built into Athena, helps provide confidentiality.

Athena's device management features, provided by the plug-ins listed in Figure 1, are exposed to calling clients such as remote desktop computers or any other device with a Web browser. Figure 2 shows the Athena service host main page as it appears when a remote Web browser requests it.

Click here for larger image

Figure 2. Athena main page. Click the thumbnail for a larger image.

The Athena server on the device handles the Web page request. You can enter either the device name or the device's IP address as the URL. Athena's main Web page lists the available plug-ins and shows them as hyperlinks. Every plug-in has its own Web page that exposes its functionality. The Athena Web pages can also be customized and redesigned.

Figure 3 shows the File Manager page, which is an example of a Web page for a plug-in.

Click here for larger image

Figure 3. File Manager plug-in. Click the thumbnail for a larger image.

Figure 4 shows another example, the Remote Control plug-in page.

Click here for larger image

Figure 4. Remote Control plug-in. Click the thumbnail for a larger image.

The following Athena plug-ins offer the following functionalities:

  • Configuration: By using the Configuration plug-in, you change the configuration settings of the Athena service host and the plug-ins.
  • File Manager: The File Manager provides access to the file system of the device and provides functionality to copy, move, rename, and delete files and folders. It also enables you to upload and download files.
  • Remote Control: You can use the Remote Control plug-in to remotely control the device by using a Web browser. The screen is captured with the ability to interact with the device. You can also save the screen to an image file.
  • System Manager: The System Manager enables you to retrieve device system information and manage the device. It provides a current list of installed applications and running processes. It also includes the functionality to install and remove applications, start and stop processes, register and unregister (COM) components, and reset the device.
  • Log Manager: The Log Manager enables you to store device information in a log that can be transmitted (pushed — a transfer initiated by the device) to a server by using file transfer (FTP) or XML Web Services (HTTP/XML). Device information can be retrieved from any of the other plug-ins.
  • Messenger: The Messenger plug-in enables you to send short messages to the device user. The messages show up as a custom message box on the device.
  • Tracker: The Tracker plug-in enables the device to report to a server. The Tracker plug-in sends regular "updates" (by means of HTTP) to a server with the identity and name of the device.

Odyssey Software is continually adding new plug-ins to Athena, and as this article was being written, a new plug-in to provide information about a device's network adapter was in the making.

That was a short introduction to Athena in general, so from a developer's perspective, next you will learn about the more interesting abilities of Athena, which are the published XML Web Service interface.

Athena for Developers

The device XML Web Services that Athena hosts can be reached from anywhere. You can use any development environment that supports the use of XML Web Services to develop applications that use Athena XML Web Services. This section focuses on Microsoft Visual Studio .NET 2003. Use the following steps to get started:

  1. Start Visual Studio .NET.

  2. Create a new project.

  3. Add a Web Reference. Enter the URL of the connected device and of the relevant Web Services Description Language (WSDL) document. The URL can point either to the name of the mobile device or to its IP address.

    Table 1 lists the plug-ins and the URL of the respective WSDL document.

Table 1. WSDL URL for Each Plug-in

Plug-in URL of WSDL document
Configuration https://device-name/wsdl/athena-configuration.wsdl
File Manager https://device-name/wsdl/athena-filemanager.wsdl
Remote Control https://device-name/wsdl/athena-remotecontrol.wsdl
System Manager https://device-name/wsdl/athena-systemmanager.wsdl
Log Manager https://device-name/wsdl/athena-logmanager.wsdl
Messenger https://device-name/wsdl/athena-messenger.wsdl
Tracker https://device-name/wsdl/athena-tracker.wsdl

Figure 5 shows the Add Web Reference dialog box after the System Manager WSDL has been found.

Click here for larger image

Figure 5. Add Web Reference dialog box. Click the thumbnail for a larger image.

You can now start using the Web Reference in your code. Athena is picked up by the IntelliSense features in Visual Studio .NET just as with any other XML Web Reference, as shown in Figure 6.

Click here for larger image

Figure 6. IntelliSense on Athena objects. Click the thumbnail for a larger image.

Almost all of the operations that you can perform with the Web page of each plug-in can be done by using the XML Web Service interface as well.

The Configuration plug-in offers the XML Web Services functionality shown in Table 2. Using the Configuration plug-in, you can retrieve all of the configuration files (by using the ListConfigFiles method) as an array of strings, and you can identify the name of the main (Athena host) configuration file with a call to GetHostConfigFile. With that information, each file can be both read and written, making it very simple to implement a remote configuration tool. Such a tool could also make the changes to the configuration file effective by either restarting Athena by calling RestartHost or performing a soft reset of the device with a call to ResetDevice.

Table 2. XML Web Services Methods for the Configuration Plug-in

XML Web Service Method Description
ListConfigFiles Get a list of configuration files.
GetHostConfigFile Get the name of the Athena host configuration file.
ReadConfigFile Read the configuration file.
WriteConfigFile Write the configuration file.
RestartHost Restart the Athena service host.
ResetDevice Reset the device.

The File Manager plug-in offers the XML Web Services functionality shown in Table 3. You can retrieve the files and folders in a specific folder of the device system by calling the ListFile method. The file information is returned as an array of FileInfo objects. You can then copy (CopyFile), move (MoveFile), rename (RenameFile), and delete (DeleteFile) each file. You can also create (CreateFolder), rename (RenameFile), and delete (DeleteFile) folders. You can upload (WriteFile) or download (ReadFile) files to or from the device. Information about a specific file can be retrieved (GetFileInfo) in addition to the amount of free memory available (GetFreeSpace).

Table 3. XML Web Services Methods for the File Manager Plug-in

XML Web Service Method Description
ListFile Retrieves a list of files on the device.
CreateFolder Creates a folder on the device.
ReadFile Retrieves a file from the device.
WriteFile Writes a file to the device.
CopyFile Copies a file on the device.
MoveFile Moves a file on the device.
RenameFile Renames a file on the device.
DeleteFile Deletes a file on the device.
GetFileInfo Retrieves information about the file on the device.
GetFreeSpace Retrieves available storage memory on the device.
GetFileHash Calculates a cryptographic hash of a file's content.
GetModuleVersion Reads the standard version info from the file.

The Remote Control plug-in offers the XML Web Services functionality shown in Table 4. You can capture the device screen (CaptureScreen), which is returned as a byte array, and you can retrieve the port that the remote control is using to receive command messages (GetActivePort).

Table 4. XML Web Services Methods for the Remote Control Plug-in

XML Web Service Method Description
CaptureScreen Captures the screen.
GetActivePort Returns the port used by the Remote Control plug-in to receive command messages.

The System Manager plug-in offers the XML Web Services functionality shown in Table 5, and its interface includes three parts. The first part is the system and device management methods that are used to get a list of the currently running plug-ins (GetServiceList); to get information about the device (GetSystemInfo); to restart Athena (RestartHost), to soft reset the device (WarmReset), or to hard reset the device (ColdReset); and to extract keys from (RegFileExport) or update (RegFileImport) the device registry. The second part covers the functionality related to application management, which uses methods to get the list of currently installed applications (GetApplicationList), to install a new application (InstallApplication), to remove an application (RemoveApplication), and to register (RegisterDLL) or unregister (UnregisterDLL) COM components (DLLs). Finally, there are process management methods that are used to get a list of currently running processes (GetProcessList) as an array of strings (GetProcessListEx) or as an array of Process objects. The process management methods also provide the ability to start a new application (StartProcess) or to stop a running application (StopProcess, StopProcessEx, KillProcess, or KillProcessEx).

Table 5. XML Web Services Methods for the System Manager Plug-in

XML Web Service Method Description
System Methods  
GetServiceList Returns available Athena services on a device.
GetSystemInfo Retrieves system information from a device.
RestartHost Restarts the Athena service host.
WarmReset Performs a soft reset of a device.
ColdReset Performs a hard reset of a device.
RegFileExport Exports a registry key to a device file.
RegFileImport Imports a registry file to a device.
Program Methods  
GetApplicationList Returns descriptions of all applications that are installed on a device.
InstallApplication Installs a .cab file on the device.
RemoveApplication Removes a previously installed application from the device.
RegisterDll Registers a COM DLL on a device.
UnregisterDll Unregisters a COM DLL on a device.
Process Methods  
GetProcessList Returns a list of descriptions for all processes that are running on a device.
GetProcessListEx Returns list (of structures including description, identity, thread count, and so on) for all processes that are running on a device.
StartProcess Starts a process on a device.
StopProcess Stops a process on a device. The process is identified by name.
StopProcessEx Stops a process on a device. The process is identified by process ID.
KillProcess Unconditionally closes a process on a device. The process is identified by name.
KillProcessEx Unconditionally closes a device process. The process is identified by process ID.

The Messenger plug-in offers the XML Web Services functionality shown in Table 6. With it, you can send an instant message (ShowPopup) to the device to notify the user of something important.

Table 6. XML Web Services Methods for the Messenger Plug-in

XML Web Service Method Description
ShowPopup Displays an urgent message in a popup window.

The Tracker plug-in offers the XML Web Services functionality shown in Table 7. You can retrieve the tracking status (by using the GetStatus method).

Table 7. XML Web Services Methods for the Tracker Plug-in

XML Web Service Method Description
GetStatus Retrieves the service status.

For more details about the XML Web Services interfaces published by Athena and Athena's plug-ins, please see the Athena documentation. Next, this article describes how you can use the previously described interfaces in a sample application.

Device Manager Sample

The following Device Manager sample was created with Visual Studio .NET 2003. The sample shows how to use the XML Web Services interface published by Athena in a customized Windows Forms application. A collection of the sample's windows is shown in Figure 7.

Click here for larger image

Figure 7. Device Manager sample windows. Click the thumbnail for a larger image.

The sample was created for scenarios in which device users send support requests that support professionals (help desk) field. Between support incidents, the support professional performs general monitoring by analyzing device usage.

When the Device Manager sample application starts, the Device Manager window contains an overview of the currently active devices, as shown in Figure 8.

Click here for larger image

Figure 8. Device overview. Click the thumbnail for a larger image.

When the support professional selects the Refresh command on the View menu (or clicks the Refresh button), a call is made to a database table that holds information about the currently active devices. The database table is updated from the devices by the Athena Tracker plug-in that submits information about the device name, IP address, port, and the time that the last update was made. The Tracker sends this information every ten minutes, so any device that has a "last update" older than ten minutes is either turned off or outside network coverage. The Athena Log Manager plug-in also provides data on a regular basis (although less frequently than the Tracker), and this data includes the device MAC address, battery and memory status, and the time that the information was submitted.

On the View menu, there are also commands to select how the device list is presented. Similar to Windows Explorer, the available views are Icons, List, and Details. Figure 8 shows the Details view, and Figure 9 shows the same list in the Icons view.

Click here for larger image

Figure 9. Icons view. Click the thumbnail for a larger image.

In any view, the support professional can right-click a device to view a shortcut menu with the following commands:

  • Open: Opens the device in the remote control window
  • Setup: Starts the application management window
  • Info: Opens the window to view device information
  • Files: Enters the device file manager

The same commands are also available on the Tools menu.

When a device is opened, the remote control window for the device is displayed, as shown in Figure 10.

Click here for larger image

Figure 10. Remote Control window. Click the thumbnail for a larger image.

In the Remote Control window, the current device screen is captured and shown. Also, the device is queried for battery and memory usage, which is presented graphically. The device screen is interactive, and the mouse can be used as a remote stylus to tap the screen. The indicators (battery and memory) are updated when the support professional clicks the Refresh icon (top right corner of the window). With the remote control, the support professional can also send an instant message to the device user by entering text in the entry field at the bottom of the window and then clicking the Send Message button.

When Setup is selected for a device in the Device Manager window (shown in Figures 8 and 9), the Manage Applications window opens, as shown in Figure 11.

Figure 11. Manage Applications window

The list in the Manage Applications window shows which applications are installed on the device. Right-clicking an application produces a shortcut menu that allows the support professional to remove the selected application. By right-clicking anywhere in the list, the support professional can install a new application with the Add command. When the support professional clicks Add, a dialog box appears in which the support professional selects a Pocket PC setup (.cab) file (probably created with some installation tool) in the file system (or on a remote network drive). When such a file is selected, it is copied to the device and setup is started.

When the support professional selects Info for a device in the Device Manager window, the Device Information window appears, as shown in Figure 12.

Figure 12. Device Information window

The Device Information window displays information that is made available by the Athena System Manager plug-in. The content includes information about Athena itself, about the system, about memory, and batteries. It also includes a list of the currently running processes on the device. If the support professional right-clicks a process and selects Stop, the device terminates that process.

When the support professional right-clicks a device in the Device Manager window and selects Files, it loads the File Manager window, as shown in Figure 13.

Click here for larger image

Figure 13. File Manager window. Click the thumbnail for a larger image.

In the File Manager window, information about the files and folders on the device can be retrieved and displayed. When the window opens, the root level is loaded (files and folder in the root of the device file system). When the support professional selects another folder and clicks the Refresh button (top right), the Athena application running on the device retrieves information about the files and folders in the selected folder. To start an application remotely, right-click an application file (.exe), and then click Start.

This sample shows some important functionality in managing devices remotely. Next, you'll look at the code behind the sample.

Code Walkthrough

Let's start with some of the hidden code on the server side.

Tracking

The first thing that happens when the sample application is set up (see instructions included with the download sample is the update of the database by the Tracker plug-in. To enable these updates, the tracker configuration file on the device needs to be updated to include entries similar to the following.

TRACKER_URL https://server/dir/tracker.aspx?
  id={ID}&name={NAME}&ip={IP}&ports={PORTS}
INITIAL_UPDATE 15
UPDATE_INTERVAL 600
RETRY_INTERVAL 30
MAXIMUM_RETRIES 5
NETWORK_TIMEOUT 10

The most interesting setting is the first (TRACKER_URL) that contains the URL that the Tracker uses to do the actual update. You replace the server part of the URL with the name or IP address of the Web server and replace dir with the virtual directory on the Web server. Note that the first setting must be on one single line, and not on two lines as in the previous code example. Other settings in the configuration file specify when the first update should be made (INITIAL_UPDATE), how often the Tracker should perform an update (UPDATE_INTERVAL), how often it should retry after a failed attempt (RETRY_INTERVAL), the maximum number of retries (MAXIMUM_RETRIES), and how long time to wait for a response from the Web server (NETWORK_TIMEOUT). All of these settings are expressed in seconds. When it is time for the Tracker to do an update, the URL is used to make a simple HTTP GET request. The information transferred in the URL is the device identity ({ID}), the device name ({NAME}), the IP addresses ({IP}), and the active ports ({PORTS}) on the device. On the server side, the update is handled by a simple ASP.NET page that is implemented like the following.

<%@ Page Language="c#" Debug="true" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%
// Get URL parameters
string deviceID = new Guid(Request.QueryString["id"]).ToString();
string deviceName = Request.QueryString["name"];
string ipAddress = Request.QueryString["ip"];
string ports = Request.QueryString["ports"];
if(ports == null)
  ports = "80";

// Update database
SqlConnection cn = new SqlConnection(connectionString);
cn.Open();
SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = "UPDATE Device SET IpAddress='" + ipAddress + "'" +
  ", DeviceName='" + deviceName + "', Port='" + ports +"'" +
  ", LastUpdate='" + DateTime.Now + "'" +
  " WHERE DeviceID='" + deviceID + "'";
int rowsAffected = cmd.ExecuteNonQuery();
if(rowsAffected < 1)
{
  cmd.CommandText = "INSERT Device (DeviceID, DeviceName," +
    " IpAddress, Port, LastUpdate) VALUES('" + deviceID + "'"
    ", '" + deviceName + "', '" + ipAddress + "'" +
    ", '" + ports +"', '" + DateTime.Now + "')";
  cmd.ExecuteNonQuery();
}
%>

The URL parameters are retrieved and a connection is set up before the call is made to populate the database. If a row for the device exists, it is updated, and, if not, it is created. The download sample includes a script for generating the required database table.

Logging

The Tracker plug-in only provides the information to the server that indicates that the device is turned on (and online), so if more information about the device is needed on the server, the Log Manager can help. By using the Log Manager you can log any information that is published (as XML Web Services) by any of the other plug-ins to a file on the device. That file can then be transmitted to a server (by using FTP or XML Web Services) with a defined frequency.

In the sample code, the Log Manager is set up with the following configuration file settings.

NETWORK ADAPTER VNETUSBA1
LOG MAXLINES 100
ATHENA PORT 80
GROUP SAMPLE1
SAMPLE1 SampleElement SystemManager GetSystemInfo {} _
  {DeviceID, DeviceName, BatteryLifePercentString, MemoryLoadString}
SAMPLE1 SampleIntervalFirst 15
SAMPLE1 SampleIntervalNormal 3600
SAMPLE1 SampleIntervalError 60
SAMPLE1 TransmitProtocol RPC   
SAMPLE1 TransmitFormat STRUCT
SAMPLE1 TransmitAction ClearLog
SAMPLE1 TransmitIntervalFirst 30
SAMPLE1 TransmitIntervalNormal 86400
SAMPLE1 TransmitIntervalError 900
SAMPLE1 RpcUrl https://server/dir/LogManager.asmx
SAMPLE1 RpcMethodName ProcessSample1
SAMPLE1 RpcProtocol SoapRpcEncodedSchema2001
SAMPLE1 RpcMethodUri urn:LogManager
SAMPLE1 RpcAction $MethodURI/$MethodName     
SAMPLE1 RpcRequestEncoding UTF8
SAMPLE1 RpcCompressionMethod None
SAMPLE1 RpcAcceptCompression False

In this portion of the code, the most interesting setting is probably the one that specifies which data should be logged (SampleElement), and in this case, it is only a few of the properties from the System Manager's system information structure. Another important setting is the one that contains the URL (RpcUrl) of the XML Web Service to transmit the log file to. Other interesting settings are the name of the network card (NETWORK ADAPTER), which is used to retrieve the MAC and IP address of the device, the time that the first sample should be taken (SampleIntervalFirst), how often samples should be taken (SampleIntervalNormal), when the first transfer of the log to the server takes place (TransmitIntervalFirst), and how often transfers should be made (TransmitIntervalNormal). The time values are all expressed in seconds.

On the server side, the transfer is handled by a simple ASP.NET XML Web Service method that is implemented like the following.

[WebMethod, SoapRpcMethod]
public void ProcessSample1(LogManagerDataTypes.Sample[] logData)
{
  // logData will be null if there is a protocol mismatch.
  if (logData != null)
  {
    LogManagerDataTypes.Sample sample = logData[0];

    // Check method ok
    LogManagerDataTypes.LogManagerMethod method = sample.GetSystemInfo;
    if (method == null)
      return;
    else
      if(method.ErrorCode != 0)
        return;

    // Get device ID
    string deviceID = new
      Guid(sample.GetSystemInfo.Results.DeviceID).ToString();

    // Update database row
    SqlConnection cn = new SqlConnection(connectionString);
    cn.Open();
    SqlCommand cmd = cn.CreateCommand();
    cmd.CommandText = "UPDATE Device SET DeviceName='" +
      sample.GetSystemInfo.Results.DeviceName + "'" +
      ", MacAddress='" + sample.MacAddress + "'" +
      ", BatteryLife='" +
      sample.GetSystemInfo.Results.BatteryLifePercentString +
      "', MemoryLoad='" +
      sample.GetSystemInfo.Results.MemoryLoadString + "'" +
      ", SampleTime='" + sample.SampleTime.ToString() + "'" +
      " WHERE DeviceID='" + deviceID + "'";
    cmd.ExecuteNonQuery();
  }
}

The method name is defined by the RpcMethodName parameter in the configuration file (see previous code example). The name was selected because this method will process the information from the first sample (SAMPLE1, see the previous configuration file). The device log file information (the samples) for the device comes as an array of a type defined by Athena (Sample) in a certain namespace ("LogManagerDataTypes") that includes the definitions of all functionality published by the Athena plug-ins. The parameter (logData) must be declared as an array as there may be more than one sample in the log file. Each sample will be an item in the array. After the first (and in this case only) sample is selected in the parameter, some general checks verify that the status of the transfer (the XML Web Service call) is successful. If everything is fine, the device name is retrieved, the database connection is set up, and the device row in the database is updated with the information from the transferred log file sample.

By using this technique, you can log all sorts of information and push it to the server where statistical data can later be analyzed.

Desktop Computer Console

So, with the database updated with the device information, next you will turn to the Device Manager sample application. The first thing that happens in the main form is a query of the database to fill the device list, as shown in the following code.

// Get device data
SqlConnection cn = new SqlConnection(connectionString);
cn.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Device" +
    " WHERE DATEDIFF(s, LastUpdate, GETDATE()) <= 600", cn);
DataSet ds = new DataSet();
da.Fill(ds);

// Fill ListView from DataSet
ListViewItem lvi;
listView.BeginUpdate();
listView.Items.Clear();
foreach (DataRow dr in ds.Tables[0].Rows)
{
    lvi = new ListViewItem(dr["DeviceName"].ToString());
    lvi.SubItems.Add(dr["IPaddr"].ToString());
    lvi.SubItems.Add(dr["Port"].ToString());
    lvi.SubItems.Add(dr["LastUpdate"].ToString());
    lvi.SubItems.Add(dr["MacAddress"].ToString());
    lvi.SubItems.Add(dr["BatteryLife"].ToString());
    lvi.SubItems.Add(dr["MemoryLoad"].ToString());
    lvi.SubItems.Add(dr["SampleTime"].ToString());
    lvi.SubItems.Add(dr["DeviceID"].ToString());
    lvi.ImageIndex = 0;
    listView.Items.Add(lvi);
}
listView.EndUpdate();

Just as in the ASP.NET page, the database connection (and adapter) is set up, and a DataSet is filled with the devices that have reported an update within ten minutes. If the Tracker is set up to report every ten minutes, and the last update from a device was performed more than ten minutes ago, the device is probably not available (turned off, outside network coverage, and so on).

When you right-click a device in the list and select a shortcut menu command, a new window is opened as a modeless dialog box. You can open as many windows as you want (even for the same device).

When you select Open on the shortcut menu, the remote control form (OpenForm) is displayed. The first thing that happens in that form is that the device screen is captured and the device indicators (battery and memory) are updated. This is also what happens when the support professional clicks the Refresh button. The device screen is captured by using the following code.

webBrowser.Navigate("https://" + this.deviceName +
    "/RemoteControl/index.html");

As you can see, the code uses a Web browser control (actually an imported ActiveX control) that connects to a Web page on the device (note that the original index.html file must be replaced with the one supplied in the sample code). The Web page on the device contains a Java applet that enables the desktop application to interact remotely with the device. Therefore, you must install Java Virtual Machine on the desktop computer to enable this functionality.

However, if interactivity is not needed, you can save bandwidth by using the following code to capture the screen by using the Remote Control XML Web Service.

WebServices.RemoteControl remoteControl =
    new WebServices.RemoteControl();
remoteControl.Url = remoteControl.Url.Replace("localhost",
    this.deviceName);
byte[] screen = remoteControl.CaptureScreen("bmp", 16);
MemoryStream m = new MemoryStream(screen);
capturePictureBox.Image = new System.Drawing.Bitmap(m);

The Remote Control Web Reference is instantiated, and the URL is updated with the device name (passed to the form's constructor from the main form). Then, the screen is captured (CaptureScreen) in bitmap format and a color depth of 16 bits. The returned byte array is saved in a memory stream that in turn is used to create a bitmap that is passed to the picture box control.

The battery and memory indicators also use another Web Reference, the one for the System Manager XML Web Service. The code to get the current battery and memory status looks like the following.

WebServices.SystemManager systemManager =
    new WebServices.SystemManager();
systemManager.Url = systemManager.Url.Replace("localhost",
    this.deviceName);
WebServices.SystemInfo systemInfo = systemManager.GetSystemInfo();
setBatteryLevel(systemInfo.BatteryLifePercent);
setMemoryLevel(systemInfo.MemoryLoad);

The actual indicators (simply two Panel controls) are updated with this code:

private void setBatteryLevel(int level)
{
    batteryPanel.Top = batteryFramePanel.Height –
        (level * batteryFramePanel.Height / 100);
    batteryPanel.Height = batteryFramePanel.Height –
        batteryPanel.Top;
}

The memory indicator update method looks very similar.

When text is entered in the text box at the bottom on the form and the Send Message button is clicked, the following code is executed.

WebServices.Messenger messenger =
    new WebServices.Messenger();
messenger.Url = messenger.Url.Replace("localhost",
    this.deviceName);
messenger.ShowPopup(messageTextBox.Text, 14, true);

The message in the text box is sent with a font size of 14 points. When the message arrives (indicated by the last parameter), the device emits a beep .

When the support professional selects a device in the list on the main form, and then selects Setup on the shortcut menu, the application management form (SetupForm) is displayed. When the form is loaded, the first thing that happens is the list of applications are loaded. This is also what happens when the support professional clicks the Refresh button in that form. The list of installed applications is filled by using the following code.

WebServices.SystemManager systemManager =
    new WebServices.SystemManager();
systemManager.Url = systemManager.Url.Replace("localhost",
    this.deviceName);
string[] applications = systemManager.GetApplicationList();

ListViewItem lvi;
listView.BeginUpdate();
listView.Items.Clear();
foreach(string application in applications)
{
    lvi = new ListViewItem(application);
    listView.Items.Add(lvi);
}
listView.EndUpdate();

The list of installed applications is retrieved as a string array from the System Manager Web Reference, and the list is updated with the application names. When you right-click an application in the list, and then click Remove on the shortcut menu, the following code is run.

WebServices.SystemManager systemManager =
    new WebServices.SystemManager();
systemManager.Url = systemManager.Url.Replace("localhost",
    this.deviceName);

// Get application name
string applicationName =
    listView.Items[listView.SelectedIndices[0]].Text;

// Ask to be sure
if(MessageBox.Show("Are you sure you want to remove" +
    " application '" + applicationName + "'?", this.Text,
    MessageBoxButtons.YesNo, MessageBoxIcon.Question,
    MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
        // Remove application
        systemManager.RemoveApplication(applicationName);
        MessageBox.Show("'" + applicationName + "' removed!", this.Text);
        refresh();
}

After the System Manager Web Reference instance is set up and the application name is retrieved from the ListView, the support professional is asked for a confirmation before the method to remove the application (RemoveApplication) is called. This call to the System Manager XML Web Service is similar to how the list of installed applications was retrieved (see above).

If the Add command on the shortcut menu is selected, the following code is executed.

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.DefaultExt = "cab";
openFileDialog.Filter = "Cab files (*.cab)|*.cab";
if(DialogResult.OK == openFileDialog.ShowDialog() &&
    openFileDialog.FileName.Length > 0)
{
    string hostPath = openFileDialog.FileName;
    // Set up XML Web Services
    WebServices.FileManager fileManager =
        new WebServices.FileManager();
    fileManager.Url = fileManager.Url.Replace("localhost",
        this.deviceName);
    WebServices.SystemManager systemManager =
        new WebServices.SystemManager();
    systemManager.Url = systemManager.Url.Replace(
        "localhost", this.deviceName);

    // Copy file to device
    string devicePath = @"\" + Path.GetFileName(hostPath);
    FileStream fs = File.OpenRead(hostPath);
    byte[] buffer = new byte[fs.Length];
    fs.Read(buffer, 0, buffer.Length);
    fileManager.WriteFile(devicePath, buffer, true, false);
    
    // Install
    systemManager.InstallApplication(devicePath);
    MessageBox.Show("Application added!", this.Text);
}

First, the code produces a standard dialog box in which the support professional selects a setup (.cab) file. If a file is selected, the file and System Manager Web Reference instances are set up. Then, after some manipulation to get the setup file data as a byte array, the File Manager is used to copy the file to the device (WriteFile). After the file is copied to the device, a System Manager method (InstallApplication) is used to install the setup file. When the setup is complete, a confirmation message is shown. As is the case in any device application install, you may need to perform actions that are required on the device side to complete the setup (the device user should check the device screen for any additional installation instructions).

When the support professional selects a device in the list in the main form, and then selects Info on the shortcut menu, the device information form (InfoForm) is displayed. The first thing that happens in that form is the same outcome as when the support professional clicks the Refresh button. A tree is filled with information about the device by using the following code.

WebServices.SystemManager systemManager =
    new WebServices.SystemManager();
systemManager.Url = systemManager.Url.Replace("localhost",
    this.deviceName);
WebServices.SystemInfo systemInfo = systemManager.GetSystemInfo();
WebServices.Service[] services = systemManager.GetServiceList();
WebServices.Process[] processes = systemManager.GetProcessListEx();

TreeNode node;
treeView.BeginUpdate();
treeView.Nodes.Clear();

node = treeView.Nodes.Add("Athena");
node.Nodes.Add("Athena version: " +
    systemInfo.AthenaVersionString);
foreach(WebServices.Service service in services)
    node.Nodes.Add(service.ServiceName + ": v" +
        service.ServiceVersion + ", " + service.ServiceModule);

node = treeView.Nodes.Add("System");
node.Nodes.Add("Device ID: " + systemInfo.DeviceID);
node.Nodes.Add("Device Name: " + systemInfo.DeviceName);
node.Nodes.Add("Device Description: " +
    systemInfo.DeviceDescription);
node.Nodes.Add("Owner Name: " + systemInfo.OwnerName);
node.Nodes.Add("OEM Info: " + systemInfo.OEMInfo);
node.Nodes.Add("Platform Type: " + systemInfo.PlatformType);
node.Nodes.Add("Processor Architecture: " + systemInfo.ProcessorArchitectureString);
node.Nodes.Add("Processor Type: " +
    systemInfo.ProcessorTypeString);
node.Nodes.Add("Processor Level: " + systemInfo.ProcessorLevel.ToString());
node.Nodes.Add("Processor Revision: " + systemInfo.ProcessorRevision.ToString());

node = treeView.Nodes.Add("Operating System");
node.Nodes.Add("OS Version: " + systemInfo.OsVersionString);
node.Nodes.Add("Platform ID: " + systemInfo.OsPlatformIdString);
node.Nodes.Add("CSD Version: " + systemInfo.OsCsdVersion);

node = treeView.Nodes.Add("Memory");
node.Nodes.Add("Memory Load: " +
    systemInfo.MemoryLoadString);
node.Nodes.Add("Available Physical Memory: " + systemInfo.AvailablePhysicalMemoryString);
node.Nodes.Add("Total Physical Memory: " + systemInfo.TotalPhysicalMemoryString);
node.Nodes.Add("Available Page File: " + systemInfo.AvailablePageFileString);
node.Nodes.Add("Total Page File: " +'
    systemInfo.TotalPageFileString);
node.Nodes.Add("Available Virtual Memory: " + systemInfo.AvailableVirtualMemoryString);
node.Nodes.Add("Total Virtual Memory: " + systemInfo.TotalVirtualMemoryString);

node = treeView.Nodes.Add("Main Battery");
node.Nodes.Add("AC Line Status: " +
    systemInfo.ACLineStatusString);
node.Nodes.Add("Status: " +
    systemInfo.BatteryFlagString);
node.Nodes.Add("Life Percent: " +
    systemInfo.BatteryLifePercentString);
node.Nodes.Add("Life Time: " +
    systemInfo.BatteryLifeTimeString);
node.Nodes.Add("Full Life Time: " +
    systemInfo.BatteryFullLifeTimeString);
node.Nodes.Add("Voltage: " +
    systemInfo.BatteryVoltageString);
node.Nodes.Add("Current: " +
    systemInfo.BatteryCurrentString);
node.Nodes.Add("Average Current: " + systemInfo.BatteryAverageCurrentString);
node.Nodes.Add("Average Interval: " + systemInfo.BatteryAverageIntervalString);
node.Nodes.Add("mAHour Consumed: " + systemInfo.BatterymAHourConsumedString);
node.Nodes.Add("Temperature: " +
    systemInfo.BatteryTemperatureString);
node.Nodes.Add("Chemistry: " +
    systemInfo.BatteryChemistryString);

node = treeView.Nodes.Add("Backup Battery");
node.Nodes.Add("Status: " +
    systemInfo.BackupBatteryFlagString);
node.Nodes.Add("Life Percent: " + systemInfo.BackupBatteryLifePercentString);
node.Nodes.Add("Life Time: " +
    systemInfo.BackupBatteryLifeTimeString);
node.Nodes.Add("Full Life Time: " + systemInfo.BackupBatteryFullLifeTimeString);
node.Nodes.Add("Voltage: " +
    systemInfo.BackupBatteryVoltageString);

TreeNode nod;
node = treeView.Nodes.Add("Processes");
foreach(WebServices.Process process in processes)
{
    nod = node.Nodes.Add(process.ProcessName + ": ID=" +
    process.ProcessIdString + ", CPU=" + process.CpuTime);
    nod.Tag = process.ProcessName;
}
treeView.EndUpdate();

The System Manager is used to get the general system information (GetSystemInfo) that is inserted in the TreeView control into separate root nodes. The first node, named Athena, contains the Athena version number and information about the running plug-ins (services). The information about the plug-ins is retrieved (GetServiceList) in an array of a type (Service) defined by the System Manager Web Reference. This type includes a number of properties (ServiceName, ServiceVersion, ServiceModule, and so on) that is used to add child nodes to the first root node. In a similar way, the running processes are retrieved (GetProcessListEx) as an array of a custom type (Process) and then added as child nodes to the last root node (named Processes). Note also that the name of the process is added to a child node property (Tag).

This property (Tag) is used when a support professional right-clicks the node and then selects Stop.The following code is run.

WebServices.SystemManager systemManager = new WebServices.SystemManager();
systemManager.Url = systemManager.Url.Replace("localhost", this.deviceName);

systemManager.StopProcess(s);
MessageBox.Show("Process stopped!", this.Text);

The System Manager stops the process (StopProcess), and a confirmation message is displayed.

When a support professional selects a device in the list on the main form, and then selects Files on the shortcut menu, the File Manager form (FileForm) is displayed. The first thing that happens in that form is the same outcomes as when the support professional clicks the Refresh button. The TreeView and ListView controls are filled with folder and file information from the device file system by using the following code.

WebServices.FileManager fileManager =
    new WebServices.FileManager();
fileManager.Url = fileManager.Url.Replace("localhost",
    this.deviceName);

string currentDir;
TreeNode currentNode;
if(treeView.Nodes.Count < 1)
{
    currentDir = @"\";
    currentNode = treeView.Nodes.Add(currentDir); 
    currentNode.Tag = currentDir;
    treeView.SelectedNode = currentNode;
}
else
{
    currentNode = treeView.SelectedNode;
    currentDir = currentNode.Tag.ToString();
}

WebServices.FileList files =
    fileManager.ListFiles(currentDir, "Name");

TreeNode node;
treeView.BeginUpdate();

ListViewItem lvi;
listView.BeginUpdate();
listView.Items.Clear();

foreach(WebServices.FileInfo fileInfo in files.List)
{
    if(fileInfo.Attributes.IndexOf("D") > -1)
    {
        node = currentNode.Nodes.Add(fileInfo.Name);
        node.ImageIndex = 0;
        if(currentDir == @"\")
            node.Tag = currentDir + fileInfo.Name;
        else
            node.Tag = currentDir + @"\" + fileInfo.Name;
    }
    else
    {
        long size = fileInfo.SizeHigh * Int32.MaxValue +
            fileInfo.SizeLow;
        string s;
        if(size > 1024L * 1024L)
            s = string.Format("{0:0}", size /
                (1024L * 1024L)) + " MB";
        else if(size > 1024L)
            s = string.Format("{0:0}", size /
                1024L) + " KB";
        else
            s = string.Format("{0:0}", size) + " B";
        lvi = new ListViewItem(fileInfo.Name);
        lvi.SubItems.Add(s);
        lvi.SubItems.Add(fileInfo.Type);
        lvi.SubItems.Add(fileInfo.Date.ToString());
        lvi.SubItems.Add(fileInfo.Attributes);
        listView.Items.Add(lvi);
    }
}
listView.EndUpdate();
treeView.EndUpdate();

If this is the first time the code is run, the root node (\) is selected, and the form is filled using that folder. The list of files is retrieved (ListFiles) by using a File Manager Web Reference instance. The method takes the requested folder as the first parameter, and the sort order as the second (here the files are sorted according to their names). The method returns an array of a type (FileInfo) defined by the File Manager Web Reference. The folders are filled in the TreeView and the files are filled in the ListView, which contains information about each retrieved file from the file information (fileInfo) object. Note that the full path is saved in the Tag property of each node in the TreeView to be used when information is requested for that node. When a new directory is selected in the TreeView, click the Refresh button (top right corner of the window) to retrieve the new folder's information.

If an application file (.exe) is right-clicked in the ListView and Start is selected on the shortcut menu, the application is started by using the following code.

string applicationPath =
    treeView.SelectedNode.Tag.ToString() + @"\" +
    listView.Items[listView.SelectedIndices[0]].Text;

WebServices.SystemManager systemManager = new WebServices.SystemManager();
systemManager.Url = systemManager.Url.Replace("localhost", this.deviceName);

systemManager.StartProcess(applicationPath, string.Empty);
MessageBox.Show("Application started!", this.Text);

The full path of the file is created by using the information in both the TreeView and the ListView, and then the System Manager is used to start the application (StartProcess).

This last form could easily be extended into a complete file manager application. The functionality published by the File Manager plug-in includes methods to create, rename, and delete folders in addition to copy, rename, move, and delete files.

For more details, please see the download sample.

Conclusion

The fact that device management can be very different for different enterprises makes the ability to customize support applications appealing. Using standard technology like XML Web Services to access devices remotely gives a device administrator a powerful tool to support device users. Athena enables this tool by making the device management functionality available as XML Web Services. The native support for XML Web Services that is built into the development tools makes it easy to implement customized device management applications.