xAP Bridge


Build 279 was the last build to have this module
Using xap_serial you can achieve much the same thing

See also xap_serial for an even simpler serial interface. This is more useful if you already have a Serial device and you want to xAP enable it.

Protocol Definition Bridging

xAP is, so far is as practicable, network agnostic. Where two networks are to be joined, so that xAP messages can be passed between then, a software bridge is used. The bridge understands the implementation details of the xAP protocol on each physical network, and performs the necessary protocol conversions to pass the message from one network to another. In some cases, the bridge may provide a configuration interface to allow traffic in one or both directions to be restricted. A proposal has been made to permit messages to be flagged “non-routable” in the xAP-Header, and for bridges to never pass these messages. Currently this item is still open. Messages passed over the bridge always have the xAP-header hop count increased. A bridge may be configured to discard messages with hop-count > n to prevent looping/broadcast storms.


The xap-bridge will allow xAP compliant hardware to extend the functionality of the HAH livebox implementation.

Using a USB hub and a set of RS232/USB adapters, such as the ubiquitous Prolific USB-to-serial dongle, a large number of external hardware devices can be supported.

This configuration of xap-hub/xap-bridge can also be run standalone on any Linux based system, allowing xAP hardware modules to be placed else where on your network and be coordinated / logged by the HAH controller.

The bridge not only acts as a Ethernet/Serial gateway it allows serial devices on different ports to communicate with one another too. For example a message originating on /dev/ttyUSB0 can be forwarded to every other serial port AND the Ethernet.

The xAP serial devices must wrap their xAP message in a Transport Wrapper for the bridge to be able to process the inbound message.

The xAP bridge uses two threads separated by a FIFO (First in First Out) buffer to hold packets generated on fast networks for transmission to the slow networks, typically for the Ethernet to serial flow, but also high speed serial to low speed serial. Packets for transmission will not time out whilst sitting in the queue however once popped from the queue a serial port must send a packet within 4.5sec otherwise the port will be disabled for transmission, this is to prevent slow, misconfiguration, or disconnected serial ports from blocking the bridge from processing its data in a timely fashion. Once TX disabled the port, if full duplex, can still send data to the bridge but the bridge will not forward packets to it.

The Rx Thread processes all serial data through the state machine above, the state is preserved for each serial port and as the data stream is read the machine continues to process the bytes until a valid xAP packet is produced.

The xAP bridge will use the common /etc/xap-livebox.ini configuration file to setup each serial port participating in the bridge. Each Serial port will begin with the letter s followed by a number, these must be sequential, as configuration set-up will stop when a missing number is found. Given this sequential requirement to allow commenting the data may be commented out instead of the line.

s1=/dev/ttyS0:B38400 CLOCAL IGNBRK CS8 CREAD:RX
  • enable default 0. This attribute is examined by the /etc/init.d/xap startup script and determines if the bridge will be started as a service when the livebox boots up.
  • hop-count default 5. As a packet passes through the bridge its hop count will be incremented packets can be dropped if they exceed a certain number of hops.
  • forwardHeartbeats default 0 (off). Heartbeats sent from a serial device will, by default, only propagate to the Ethernet and not to other serial devices, nor will serial device heart beats be sent to other serial devices. If you wish these packet types to pass transparently and be forwarded everywhere set this to 1.
  • s<digit> - The format of the data line is <device>:<termios>:<xmit>

<device> is a service device file path.

<termios> are strings allowed by the termios(3) Linux manual page see detailed descriptions below.

The <xmit> directive indicates, from the bridges point of view, the direction of traffic.

  • TX - The bridge will send data to the serial port but never read anything from it.
  • RX - the most common scenario, the micro controller will generate data for the bridge to receive but does not accept data for processing. The micro is operating as a pure event generator.
  • TX RX - a full duplex conversation.

If you not specify at least one TX or RX option you'll effectively disable the port. The xmit directive helps reduce the workload on the bridge when prior knowledge about the traffic on the serial interface is known, if you don't know supply TX RX.

A serial port on a bridge may supply data to a serial port running yet another bridge. In this way serial cables can be used to extend the reach of your xAP network increasing the hop count at each bridge.

Browse source http://code.google.com/p/livebox-hah/source/browse/#svn/trunk/userapps/hah/xap-bridge

Linux executable R29 xap-bridge-linux-i386.tar.gz

Input Modes

Values of the c_iflag field describe the basic terminal input control, and are composed of following masks:

           IGNBRK   /* ignore BREAK condition */
           BRKINT   /* map BREAK to SIGINTR */
           IGNPAR   /* ignore (discard) parity errors */
           PARMRK   /* mark parity and framing errors */
           INPCK    /* enable checking of parity errors */
           ISTRIP   /* strip 8th bit off chars */
           INLCR    /* map NL into CR */
           IGNCR    /* ignore CR */
           ICRNL    /* map CR to NL (ala CRMOD) */
           IXON     /* enable output flow control */
           IXOFF    /* enable input flow control */
           IXANY    /* any char will restart after stop */
           IMAXBEL  /* ring bell on input queue full */
           IUCLC    /* translate upper case to lower case */

Output Modes

Values of the c_oflag field describe the basic terminal output control, and are composed of the following masks:

           OPOST   /* enable following output processing */
           ONLCR   /* map NL to CR-NL (ala CRMOD) */
           OXTABS  /* expand tabs to spaces */
           ONOEOT  /* discard EOT's `^D' on output) */
           OCRNL   /* map CR to NL */
           OLCUC   /* translate lower case to upper case */
           ONOCR   /* No CR output at column 0 */
           ONLRET  /* NL performs CR function */
           NL0     /* Newline delay type 0. */
           NL1     /* Newline type 1. */
           CR0     /* Carriage-return delay type 0 */
           CR1     /* Carriage-return delay type 1 */
           CR2     /* Carriage-return delay type 2 */
           CR3     /* Carriage-return delay type 3 */
           TAB0    /* Horizontal-tab delay type 0 */
           TAB1    /* Horizontal-tab delay type 1 */
           TAB2    /* Horizontal-tab delay type 2 */
           TAB3    /* Horizontal-tab delay type 3 */
           XTABS   /* equiv type 3 - expand tabs to spaces */
           BS0     /* Backspace delay type 0 */
           BS1     /* Backspace delay type 1 */
           VT0     /* vertical-tab delay type 0 */
           VT1     /* vertical-tab delay type 0 */
           FF0     /* form feed delay type 0 */
           FF1     /* form feed delay type 1 */

Control Modes

Values of the c_cflag field describe the basic terminal hardware control, and are composed of the following masks. Not all values specified are supported by all hardware.

           CS5         /* 5 bits (pseudo) */
           CS6         /* 6 bits */
           CS7         /* 7 bits */
           CS8         /* 8 bits */
           CSTOPB      /* send 2 stop bits */
           PARENB      /* parity enable */
           PARODD      /* odd parity, else even */
           HUPCL       /* hang up on last close */
           CREAD       /* enable receiver */
           CLOCAL      /* ignore modem status lines */
           CRTSCTS     /* Enable RTS/CTS (hardware) flow control */

Local Modes

Values of the c_lflag field describe the control of various functions, and are composed of the following masks.

           ISIG        /* enable signals INTR, QUIT, [D]SUSP */
           ICANON      /* canonicalize input lines */
           XCASE       /* If ICANON is also set, terminal is upper-case only. */
           ECHO        /* enable echoing */
           ECHOE       /* visually erase chars */
           ECHONL      /* echo NL even if ECHO is off */
           ECHOCTL     /* echo control chars as ^(Char) */
           ECHOPRT     /* visual erase mode for hardcopy */
           ECHOKE      /* visual erase for line kill */
           FLUSHO      /* output being flushed (state) */
           NOFLSH      /* don't flush after interrupt */
           TOSTOP      /* stop background jobs from output */
           NOKERNINFO  /* no kernel output from VSTATUS */
           PENDIN      /* XXX retype pending input (state) */
           IEXTEN      /* enable DISCARD and LNEXT */


The input baud rate is assumed to be the same as the output baud rate and must be one of these constants. A missing rate will default to B38400.


Bridge tester

A simplistic xAP message generator for the AVR-SDK1 development board. No CRC16 is being calculated instead four dashes, in line with the specification, are being emitted.

Configuration for our bridge:


MEGA-8 source code to generate an xAP message every 3 seconds.

'* xAP message generator
'* Language:       BASCOM-AVR
' Compile for the AVR-SDK board
$regfile = "m8def.dat"
$crystal = 4000000
$baud = 9600
Dim I As Bit
Config Pinc.0 = Input                                       ' Button 1
Config Pind.7 = Output                                      ' LED

Set Portd.7
  Print "{002}";
  Print "xap-header"
  Print "{"
  Print "v=12"
  Print "hop=1"
  Print "uid=FF00DB00"
  Print "class=xAPBSC.event"
  Print "source=dbzoo.micro.avrsdk"
  Print "}"
  I = Not Pinc.0                                            ' Pressed = LOW
  Print "output.state"
  Print "{"
  Print "state = " ; I
  Print "}"
  Print "----{003}";
  Wait 3
  Toggle Portd.7

Bridge aware hardware - an RF Receiver

This section discusses Work in Progress - if you want to help push this along, drop a note on the forum. Code/hardware/ideas/cash all gratefully accepted!

The Livebox PCB has a built in RF Transmitter. However, there is no 'receive' capability. This note details how we will add a RF receiver. RF reception is rather more difficult than RF transmission. There are a load of factors to consider when designing the receiver circuitry. The power supply must be 'clean' the groundplane must be good. After some experimentation, it was decided to use an existing, proven, RF receiver. We tap the RF pulsetrain signal from one of our Lidl RF mains modules and feed this to a microcontroller.

A Nokia phone USB cable will connect the microcontroller UART to the Livebox.

The USB phone cables that we purchased have three conductors. Wire colours are as follows (if you buy your own cable, the colours may well be different) :

Pin 8 - Orange - Ground
Pin 7 - Red - Phone Tx
Pin 6 - Blue - Phone Rx

The first physical device that we will look to support is an RF PIR unit.

This PIR has a ten way dip switch to allow the 'house code' to be set. Hooking the output of this up to a 'scope gives us the following waveforms Scope screenshots

As you can see, there are 41 'pulses' in the bit-stream. The bitstream is repeated several times - this is normal behaviour for RF transmitters of this sort.

A test rig was assembled to hookup the Rx socket to the AVR micro. The 'data out' line is hooked directly to the Int1 line on the AVR. By default (when no RF signal is being received), the data out pin seems to change state to 'hi' every 20mS or so, staying hi for at least 10mS before returning low again.

So, our code must cope with this behaviour. The initial design is as follows:

Configure an interrupt to occur whenever a falling edge is detected on the Int1 pin - easy to do this in Bascom. When we get the interrupt, start a timer then wait for the next rising edge of the stream. Since the time for a valid pulse is so very much shorter for that of an invalid one, the time difference will be easily noticed.

In order to build up a 'unique' id for the different patterns that the PIR can emit (based on the DIP switch settings), we use some of the 32 bits in a 'long' variable to track the long and short pulses.

Running the prototype gives solid results with reliable reception. The next job will be to design a PCB to hold the micro.