xAP Plug-in for SqueezeCenter v7.x

Edward Pearson

ersp — design

September 2008

Revision History
Revision v1.1 02-Oct-2008 ersp
Accompanies v2.2.1 software.
Revision v1.0 14-Sep-2008 ersp
First release. Accompanies v2.2 software.
Revision v0.5 10-May-2008 ersp
Draft notes for beta software testers.

Table of Contents

1. Introduction
2. Installation
3. Configuration Settings
4. xAP Communications
4.1. General
4.2. Player Basic Status and Control (BSC)
4.3. Player Transport
4.4. Player Audio Mixer
4.5. Player Schedule
4.6. Player Query
4.7. Player On Screen Display (OSD)
4.8. Player Playlist
4.9. Buttons and IR
4.10. Server Control
5. Diagnostics

1. Introduction

The xAP Plug-in for SqueezeCenter adds home automation capabilities via the xAP automation protocol to the Slim Devices' SqueezeCenter media server and players.

xAP is a set of conventions that allows home automation devices connected to a home network to exchange information and control each other. xAP is not any particular piece of software or hardware; it’s a standard created to help programs and devices created by different home automation manufacturers and enthusiasts talk to each other. There are already a considerable number of things that speak xAP and the number is growing all the time. There are new devices and programs that have been created from the ground up to work with xAP as well as existing programs and devices that are getting xAP-enabled. Enabling an existing program or device to work with xAP can be done either by the original manufacturer or, for programs that include a facility for others to create extensions or plug-ins, by someone else. The plug-in for SqueezeCenter is that last kind; a plug-in written by a third party that enables SqueezeCenter to talk xAP.

This is a second generation, pure-Perl implementation of the xAP plug-in. The previous version, released in 2006 supported server software v6.x (SlimServer) which was a replacement for the earlier .Net-based SlimServer connector that used to command line interface (CLI) to SlimServer for its integration. This version has been significantly revised to work with the updated v7.x SqueezeCenter software.

The plugin provides two-way xAP communication for SqueezeCenter with the following main functions:

  • Player power and volume control with xAP BSC

  • Player transport control

  • Player mixer control

  • Player message display

  • Playlist management

  • Server control

  • Access to low-level remote button and IR codes.

2. Installation

SqueezeCenter currently lacks a plugin install feature, though it is on the roadmap. The supplied .zip file (Plugins-xAP-Plugin.zip) should be opened and the 'xAP' folder at its top level copied to the 'Plugins' directory in your SqueezeCenter installation. On Windows this is normally 'C:\Program Files\SqueezeCenter\server\Plugins'.

For further instructions and installation troubleshooting hints, look at the Slim Devices Wiki page.

Where's the code? If you're curious, the code for the plugin is in the 'lib' directory in the 'Plugins-xAP-Plugin.par' file. A .par file is a thinly-disguised (file name extension changed) .zip archive file.

3. Configuration Settings

Once installed, the plug-in appears in the list of plugins on the plugins tab of the SqueezeCenter settings web UI. You may need to scroll down to find it. Settings specific to the plug-in can be found by clicking on the "Settings" link next to the plug-in entry. The following settings can be configured using the web UI:

Update interval

xAP sends periodic heartbeats and status update messages. The default setting of 60 seconds is typical.

Remote control button messages

Choose whether to send and receive remote control button press messages to/from the xAP network. By default this is turned off as it generates a large number of messages. You only need to enable this if you are going to do some low level integration using button press information.

Remote control infrared (IR) messages

Choose whether to send and receive SlimPlayer remote control infrared (IR) code messages to/from the xAP network. By default this is turned off as it generates a large number of messages. You only need to enable this if you are going to do some very low level integration using infrared codes.

xAP message name style

When xAP integration was first done for SlimServer some messages used "SliMP3' in their class and block names since this was the name of the player product at the time. These were changed to "Slim" for the previous version of this plug-in. The plug-in accepts both forms but here you choose which form it generates for outbound messages. You only need to choose "SliMP3" if you have other devices on your network that are expecting this.

xAP version

xAP is evolving from v1.2 to v1.3. The main change that affects this plugin is the format of the xAP UID (see next setting) which has been extended. Many, but not all, xAP devices have been updated to use the new v1.3 UID format. It is suggested that you use v1.3 format unless you know that there are v1.2 only devices on your network that need to exchange messages with SqueezeCenter. v1.2 only devices will often not recognise messages in v1.3 format. v1.3 devices will recognise v1.2 messages.

xAP device ID

Each xAP device on a home network has a hex identifier that is part of its unique ID (UID). A default is automatically generated; you only need to change this if it conflicts (unlikely) with another device on your xAP network. The device ID must be a series of upper-case hexadecimal digits, eg '4E99A2F2' but not all 0's or all F's, which are reserved.

xAP IP broadcast address

Set the xAP IP broadcast address. By default this is 255.255.255.255 which is the 'limited broadcast' address. This should work with most networks and does not get routed to other networks. Change this if you need a more specific address (eg, 192.168.1.255). The most common reason to need a more specific address is if the machine running SqueezeCenter has more than one network connection (wired and wireless) or something that acts like a network connection such as a VPN or dial-up.

4. xAP Communications

The plug-in supports two-way communication between SqueezeCenter and a xAP network. Firstly it takes status information from SqueezeCenter (like what’s playing) and pushes it out onto the xAP network. Secondly it listens for relevant messages on the xAP network and acts on them. Pausing a player, for example.

On its own the plug-in is of little use; it has nothing to talk to. It becomes useful when you have another xAP-enabled device or program that can understand the messages the plug-in sends or can create messages for the plug-in to receive. These other components are commonly home automation control programs like HomeSeer, HouseBot and Girder that can control SqueezeCenter (eg, stop all players when you leave the house) or devices that generate information that can usefully be displayed on SlimPlayer screens like telephone caller ID, security alerts and reminders.

4.1. General

This section covers some general topics that relate to all areas of xAP communications. The subsequent sections each cover the details of a particular functional aspect of the plug-in.

xAP Schema

The xAP plug-in for SqueezeCenter supports messages from these xAP schema specifications:

  • Basic Status and Control (BSC) v1.3

  • Audio and Media Control v2.2 with SqueezeCenter-specific extensions

  • On Screen Display (OSD) with SqueezeCenter-specific extensions.

Naming

Although SlimServer is now officially named SqueezeCenter, the xAP message schema for this plugin continue to use "SlimServer" and "Slim" throughout. A move to Squeeze and SqueezeCenter was considered but rejected. This was done to promote stability and interoperability between xAP installations. Synonyms for messages that historically used the original "SliMP3" were already introduced in v1; to introduce a futher set for v2 would only lead to needless configuration fault-finding.

Addressing

The name used for the SlimServer's xAP source address is ersp.SlimServer.hostname where "hostname" is the name of the computer it's running on. On my setup the server is called "Pacific" so you will see the line:

Source=ersp.SlimServer.Pacific

in the header section of the example messages sent by my SqueezeCenter in this document.

The current version of the xAP plug-in does not require a xAP target address to be set on messages sent to the plugin for any of the message types other that the Basic Status and Control (BSC) messages. Messages sent with no target will be acted on by all SqueezeCenter servers and applied to all connected players in the case of player-specific messages. Historically this was a handy shortcut in a simple xAP network but it is no longer viewed as good practice so this behaviour will likely to be changed in a future version. Therefore it is recommended that you include a target parameter in all messages you send to the SqueezeCenter plug-in.

When sending xAP messages with a target set to your SqueezeCenter you can either the server name explicitly:

Target=ersp.SlimServer.Pacific

which you'll want to do if you run more than one SqueezeCenter, alternatively you can use the xAP wildcard address character ">" like this

Target=ersp.SlimServer.>

to send to any SqueezeCenter on your network. This approach is best even for a single SqueezeCenter as it means you won't need to change your xAP configuration even if you move or rename the machine you run SqueezeCenter on.

Players attached to SqueezeCenter are addressed on sub-addresses of the server. The sub-address name is taken from the player name with any characters (eg, spaces) not valid in a xAP address removed. On my network there are four players so I see player-specific messages being sent from the following xAP addresses:

ersp.slimserver.pacific:Study
ersp.slimserver.pacific:Office
ersp.slimserver.pacific:Bedroom
ersp.slimserver.pacific:LivingRoom

You can combine the server wildcard address with the specific sub-address of a player to send a message to a particular player while retaining the independence on any particular SqueezeCenter machine name like this:

Target=ersp.slimserver.>:Office

which will target the player "Office". So to pause (or un-pause) the player in my office I'd send the message:

xap-header
{
v=13
Hop=1
UID=FF.E2B800:0000
Class=xAP-Audio.Transport
Source=ersp.testscript.test
Target=ersp.SlimServer.>:Office
}
Audio.Transport
{
Command=Pause
}

Case is not significant in xAP source and target addresses though it is recommended you be consistent.

4.2. Player Basic Status and Control (BSC)

Synopsis

Classes accepted: xAPBSC.Cmd, xAPBSC.Query

Classes generated: xAPBSC.Info, xAPBSC.Event

Blocks generated: output.state.

output.state
{
DisplayText=(Off|Paused|Stopped|Playing)
Level=<volume>/100
State=(on|off)
}

Description

Each player is represented by a BSC level output endpoint. The endpoint's state represents the player's power state and its level represents its volume level. While this duplicates functionality also available in the xAP-Audio schema messages below, the Basic Status and Control schema is useful as it is widely implemented in home automation programs with 'plug and play'-like functionality. Each BSC player endpoint will report its status at regular intervals with a BSC.Info message.

For example, the message:

xap-header
{
v=13
hop=1
uid=FF.099B4556:0004
class=xAPBSC.Info
source=ersp.SlimServer.Pacific:Office
}
output.state
{
DisplayText=Stopped
Level=47/100
State=on
}

shows that the player in my office is currently turned on (State=On) has its volume set just under half way (47%) and it is stopped. This message is sent every 60 seconds, this interval can be changed via the Update Interval setting on the plug-in settings web UI page. Changes to either the power state or the volume level will result in a xAPBSC.Event message being sent (a xAPBSC.Event message indicates a change in values while a xAPBSC.Info message is a reminder of the current values). So pressing the volume up button on the remote for my office player causes the following xAPBSC.Event message to be sent:

xap-header
{
v=13
hop=1
uid=FF.099B4556:0004
class=xAPBSC.Event
source=ersp.SlimServer.Pacific:Office
}
output.state
{
DisplayText=Stopped
Level=48/100
State=on
}

Note that the message class line in the header is now xAPBSC.Event indicating a change and the Level line in the body block now shows 48% for the volume.

All normal Basic Status and Control functionality is supported for these endpoints including accepting xAPBSC.Cmd and xAPBSC.Query messages. For example the BSC command message:

xap-header
{
v=13
Hop=1
UID=FF.E2B800:0000
Class=xAPBSC.Cmd
Source=ersp.testscript.test
Target=ersp.SlimServer.>:Office
}
output.state.1
{
ID=*
State=Off
}

will cause the office player to turn off. Including the level parameter too will set a specific volume level:

output.state.1
{
ID=*
State=On
Level=80/100
}

Lastly the BSC player endpoints will respond to a xAPBSC.Query message:

xap-header
{
v=13
Hop=1
UID=FF.E2B800:0000
Class=xAPBSC.Query
Source=ersp.testscript.test
Target=ersp.SlimServer.>:Office
}
request
{
}

by sending a xAPBSC.Info message.

4.3. Player Transport

Synopsis

Message class accepted: xAP-Audio.Transport (or synonyms: SliMP3.Transport, Slim.Transport) with block

Audio.Transport
{
Command=(pause|play|stop|next|prev)
[Param=(on|off)]
}

or

Audio.Seek
{
Seek=(+mm.ss|-mm.ss|mm.ss)
}

Message class generated: xAP-Audio.Transport.Event

Audio.Transport
{
Duration=<mm:ss>
Elapsed=<mm:ss>
PlayerID=<xx:xx:xx:xx:xx:xx>
Remaining=<mm:ss>
Repeat=(off|track|album)
Shuffle=none
State=(stopped|paused|playing)
}

Description

The xAP-Audio.Transport messages are concerned with what a player is currently doing. Operation is similar to the transport display and controls on a CD player. Each player will generate xAP-Audio.Transport.Event messages at the update interval (60 seconds default) when not playing and once a second while playing. This message is also generated in response to a xAP-Audio.Transport command message. The player ID (MAC address) can be used for calls on the SqueezeCenter HTTP interface.

The command message has a single block either Audio.Transport or Audio.Seek. The Audio.Transport block contains one required parameter (command) and one optional parameter (param). The optional parameter can be use with the play, pause and stop commands to set an absolute state; without it the pause command acts to toggle the pause state. The next and prev commands will move to the next or previous song in the current playlist if available. The Audio.Seek command block instructs the player to move relatively forward or backwards in the current song or to an absolute time position. Whether the player can do this depends on the audio source being played.

If the command is not addressed to a particular player then all players will be afftected.

4.4. Player Audio Mixer

Synopsis

Message class accepted: xAP-Audio.Audio with block

Audio.Mixer
{
[Volume=(0…100|+nn|-nn)]
[Balance=(-100…0…+100|+nn |-nn)]
[Bass=(0…100|+nn|-nn)]
[Treble=(0...100|+nn|-nn)]
}

or

Audio.Mute
{
Mute=(On|Off|Toggle)
}

generates message class: xAP-Audio.Event with block

Audio.Mixer
{
Volume=nn
[Balance=nn]
[Bass=nn]
[Treble=nn]
}

or

Audio.Mute
{
Mute=(On|Off|Toggle)
}

respectively.

Description

The audio mixer messages are concerned with the audio output of a player. Only early versions of SlimDevices players (the original SliMP3 and the SqueezeBox v1) allowed for control of bass, treble, balance and pitch. Later players only allow for control of the volume.

If the command is not addressed to a particular player then all players will be afftected.

4.5. Player Schedule

Synopsis

Message class accepted: xAP-Audio.Schedule with block

Schedule.Sleep
{
Sleep=<seconds>
}

or

Schedule.Alarm
{
Command=(EnableAll|DisableAll)
}

Generates message class: xAP-Audio.Schedule.Event with block

Schedule.Sleep
{
Sleep=<seconds>
}

or

Schedule.Alarm
{
Command=(enableall|disableall|sound|end|snooze|snooze_end)
[ID=<alarmID>]
}

Description

The Audio.Schedule messages deal with time-based operations for the players. The Schedule.Sleep block initiates a sleep sequence for a player. After the time specified the player will fade any playing audio to zero and then turn off. The sleep parameter in the number of seconds until sleep. The Schedule.Alarm command block can enable and disable all alarms for a player. Both these commands are confirmed with a corresponding xAP-Audio.Schedule.Event message. Additionally, alarm events are reported using the xAP-Audio.Schedule.Event message class when triggered (command=sound), ended and snoozed. These messages could be used to cause your betroom lights to fade up when the alarm clock function is triggered (and off again when you press snooze).

If the command is not addressed to a particular player then all players will be afftected.

4.6. Player Query

Synopsis

Message class accepted: xAP-Audio.Query with block

Audio.Query
{
Query=(Mode|Sleep|Power|Volume|Balance|Bass|Treble)
} 

or

Track.Query
{
Query=(Time|Genre|Artist|Album|Title|Duration|Path)
}

or

Playlist.Query
{
Query=(Index|Genre|Artist|Album|Title|Duration|Path|Tracks|Shuffle|Repeat)
}

generates message class

Audio.Notification
{
Query=(Mode|Sleep|Power|Volume|Balance|Bass|Treble)
Status=<slimserver query result>
} 

or

Track.Notification
{
Query=(Time|Genre|Artist|Album|Title|Duration|Path)
Status=<slimserver query result>
}

or

Playlist.Notification
{
Query=(Index|Genre|Artist|Album|Title|Duration|Path|Tracks|Shuffle|Repeat)
Status=<slimserver query result>
[Index=<index in playlist>]
}

Description

The player query messages let you query various properties for a player's current activity. The notification response message generated includes the property queried and its current value.

If the command is not addressed to a particular player then all players will respond.

4.7. Player On Screen Display (OSD)

Synopsis

Message class accepted: Message.Display (or synonyms: xAP-OSD.Display, SliMP3.Display, Slim.Display) with block

Display.Text
{
Line1=<message text line>
[Line2=<message text line>]
[Line3=<message text line>]
[Line4=<message text line>]
[Line5=<message text line>]
[Line6=<message text line>]
[Line7=<message text line>]
[Line8=<message text line>]
[Line9=<message text line>]
[Duration=<seconds>]
[TTL=<seconds>]
[Align1=(left|centre|center)]
[Align2=(left|centre|center)]
[Type=(Queue|Immediate|Permanent)]
[Tag=<messageid>]
[Brightness=(PowerOn|PowerOff|Idle|Off|Dimmest|Dim|Bright|Brightest|0|1|2|3|4)]
[Size=(Small|Medium|Large|s|m|l)]
[Priority=<integer>]
[Screen=(1|2)]
}

or

Display.Text
{
Type=Delete
Tag=<messageid>
}

or

Display.Query
{
}

Description

The on screen display message is used to display text messages on a player's display. All block parameters apart from Line1 are optional.

  • Up to 9 lines can be specified for compatability with other display devices. In this implementation all lines after line 2 are concatenated onto the end of line 2.

  • Priority is an integer, the higher the number the more priority it is given. The message queue is re-sorted by priority after a message is added to the queue. The highest priority message will be shown at any time. A shown message will be taken off the display if a higher priority message is added to the queue. A message taken off the display in this way will return to the display for its remaining time when it re-gains highest priority on the queue.

  • A message is taken off a display either when its duration expires, a higher priority message arrives, it is cancelled via xAP or a remote control button is pressed.

  • Type=Queue is the default request type. Immediate is a priority higher than any specified by the Priority parameter. Permanent isn't really permanent, it's just quite a long time.

  • If TTL (Time To Live) is specified and that number of seconds passes between the message being enqueued and arriving at the head of the queue it will be discarded without being displayed. This is useful for low-priority status messages that are only worth displaying for a certain period of time after they are generated.

  • Brightness levels PowerOn, PowerOff, Idle, Off are the levels set on the player for each of those modes.

  • Tag is any alphanumeric string - used to reference a message for later deletion. See below.

  • Screen is for dual display Transporter (I'm not lucky enough to have one so this is untested).

  • In this version messages are displayed on a Duet Controller only briefly, the duration in not respected.

  • If the command is not addressed to a particular player then the message will be shown on all players. There is an independent message queue for each player.

The second block format is used for cancelling/deleting a message. The request can be sent to remove a previously sent display message (which must have included a tag field). If the message is on display it will be taken off the display. If the message is waiting in the queue it will be removed from the queue (and never shown).

The third block format (Display.Query) is used to request the current state of a SlimPlayer's display from SqueezeCenter. The message can be targetted at a specific player or to the server in which case all players will respond. The response is a message containing a Display.Notification block:

Display.Notification
{
Line1=Now playing (22 of 22) 
Line2=22. Disappearing Volcano
}

4.8. Player Playlist

Synopsis

Message class accepted: xAP-Audio.Playlist with block

Playlist.Track
{
Command=(Play|Append)
Track=<TrackURL>
}

or

Playlist.Track
{
Command=Delete
Track=<TrackIndex>
}

or

Playlist.Track
{
Command=Index
Track=(+nn|-nn|nn)
}

or

Playlist.Move
{
From=<index>
To=<index>
}

or

Playlist.Edit
{
Edit=(Load|Add)
Playlist=<PlaylistURL>
}

or

Playlist.Edit
{
Edit=Clear
}

or

Playlist.Album
{
Command=(Load|Append)
Artist=<artist>
Genre=<genre>
[Album=<album>]
}

or

Playlist.Shuffle
{
Shuffle=(On|Off)
}

or

Playlist.Repeat
{
Repeat=(Stop|Track|Playlist)
}

generates: xAP-Audio.Playlist.Info or xAP-Audio.Playlist.Event with block

Now.Playing
{
Album=<album title>
AlbumID=<integer>
Artist=<artist>
Duration=<mm:ss>
Genre=<genre>
Index=<position in playlist>
Path=<url of track>
Title=<track title>
TrackID=<integer>
Tracks=<# tracks in playlist>
}

Description

The commands in this section all relate to the current playlist for a player. Various operations can be performed on the playlist including moving among its tracks, rearranging the tracks, loading new songs etc. Perhaps the more significant aspect of this part of the schema though are the xAP-Audio.Playlist.Info and xAP-Audio.Playlist.Event messages that are generated at regular intervals as well as in response to one of the xAP-Audio.Playlist command messages. The .Event variation signifies a change in the playlist or the player's position in the playlist (for example the transition to the next track). The .Info version is generated regularly while a player is playing. Which fields are present in the Now.Playing block will depend on the audio source.

As an example, the following message was generated during an 80's revival moment:

Now.Playing
{
Album=You And Me Both (Remastered 2008 Edition)
AlbumID=1448
Artist=Yazoo
Duration=4:32
Genre=No Genre
Index=1
Path=file:///M:/Yazoo/You And Me Both (2008)/01 - Nobody's Diary.flac
Title=Nobody's Diary
TrackID=8144
Tracks=11
}

AlbumID and TrackID are SqueezeCenter's database identifiers. They can be used to call back into SqueezeCenter's HTTP and CLI interfaces (eg, to retreive artwork). For example, the thumbnail image for a track can be retrieved using the track id from:

http://<slimserver>:<port>/music/<trackid>/thumb.jpg

The thumbnail for the currently playing track on a player can be retieved using the playerid from:

http://<slimserver>:<port>/music/current/cover.jpg?player=<playerid>

The playerid (which can be found in a Transport.Info block) will have to be 'url escaped' in this case since it contains ':' characters that are not allowed in their raw form in a URL (the playerID is the player's ethernet MAC address).

4.9. Buttons and IR

Synopsis

Message class accepted: slim.button (synonym slimp3.button) with block

button.command
{
button=<buttonid>
}

Message class accepted: slim.ir (synonym slimp3.ir) with block

ir.command
{
code=<ircode>
}

Description

These are advanced functions and must be enabled explicitly in the confuguration web page before they will operate. This feature is more usually used to output button presses and IR codes from SqueezeCenter rather than injecting these events into SqueezeCenter. Enabling the IR function will cause the plug-in to report SqueezeCenter's internal events for every remote control IR code received, including the stream of repeat codes when a button is held down. SqueezeCenter maps these IR codes to button press events. Enabling the button function will report these button press events, including button repeat events.

IR codes are reported like this:

IR.Event
{
Code=7689e01f
Name=up
Time=1365685.29
}

with the parameters indicating:

Code

is a hex string that represents the low-level infrared code received by the sensor on the player.

Name

is the symbol name that SqueezeCenter has mapped to the IR code.

Time

is the code timestamp; the time in seconds when the code was received.

The codes and name mappings for the suplied remote control can be found in the file:

SqueezeCenter\server\IR\Slim_Devices_Remote.ir

Players with controls on the unit also generate pseudo IR codes when pressed, these are listed in:

SqueezeCenter\server\IR\Front_Panel.ir

Button presses are reported like this:

Button.Event
{
Button=up
}

where the Button parameter is the logical button name that SqueezeCentre has mapped the IR code to.

The mapping of buttons to functions can be found in the file

SqueezeCenter\server\IR\Default.map

4.10. Server Control

Synopsis

Theis message must to targeted to a specific server.

Message class accepted Slim.Server (or synonym SliMP3.Server) with block:

Server.Command
{
Command=(Rescan|Rescan playlists|Wipecache)
}

or

Player.Query
{
Command=(Count|Name|Address)
[Playerindex=<0..n>]
}

Description

The first form of this message class controls SqueezeCenter's library scanning functions. It can be used to initiate a rescan of the library or playlists.

The second form can be used to interrogate what players are connected to SqueezeCenter. Call it first with command=count to have SqueezeCenter report the number of connected players:

Player.Notification
{
Command=count
Status=4
}

You can then request the name and address for each of the players with command=name or command=address with the playerindex parameter set to a zero-based index of a player. For example:

Player.Query
{
Command=address
Playerindex=2
}

in my setup returns:

Player.Notification
{
Command=address
Status=192.168.8.109:40843
}

which is the IP address and TCP port the player is using.

5. Diagnostics

The plug-in uses the same log4perl logging package as the rest of SqueezeCenter. It defines the following message logger categories:

plugin.xap

general information on the plug-in's behaviour. A good place to start.

plugin.xap.comm

low level xAP communications including IP socket detail. Enable this to see all xAP messages sent and received by the plug-in.

plugin.xap.settings

web interface user settings (not very interesting).

plugin.xap.message

details on xAP message processing.

plugin.xap.display

detailed information on player OSD messages including message queue processing and status.

To enable logging start SqueezeCenter from the command line and use the --debug flag followed by a comma-separated list of logging settings.

For example:

perl.exe slimserver.pl --debug plugin.xap=DEBUG,plugin.xap.comm=DEBUG