Skip to content

Hacking the Dell SX2210T, part 1.

monitor-dell-sx2210t-overview2.jpg I’ve recently buy the Dell SX2210T, a dual touch monitor. And unfortunately, they are no linux support for the touchscreen part. So, i try to get it work, and it’s a pain.

1. Discovering the hell.

First, i’ve googled about NextWindow + linux. I’ve found on NextWindow website that they got some native support for some screen, and they seem to be hid compliant. Great news ! So, after reading the FAQ, adding missing configuration to Xorg, installing Xorg driver evtouch… No device detected. Some FAQS, research and days after, i’ve understand that the device is not an Input device. At least, not recognized to be one. Well, let’s try to change it !

And i came this week-end into Linux HID documentation : usb.txt, usbhid.txt, hid-core.c, hid.c, usbtouchscreen.c… and many many more. +10 for general geeky culture.
But but but, wait, why my device is not HID compliant ? And that’s the most complicated part. I’ve tryed, unfortunately, to add the 0x1924 + 0x0064 to the generic touch device part of usbtouchscreen.c. Failed. No, it’s has simple as adding product id and all.
I’ve resign myself to install Window Seven on VirtualBox, to check that the screen work, and capture USB packet with usbmon and wireshark.

After some of capture with “cat /sys/kernel/debug/usb/usbmon/1u”, i didn’t see any HID message in. Mmmh… i’m afraid… Is Dell is going to do a proprietary protocol, instead of doing HID compliant device ? Do i miss something big here ? Let’s see…

2. Feel the pain.

So, to experiment fast & easy USB protocol, i’ve used Python + libusb binding.

import usb
import sys
import struct

DELL_VENDORID = 0x1926
DELL_PRODUCTID = 0x0064

busses = usb.busses()
dev = None
for bus in busses:
    for device in bus.devices:
        if device.idVendor != DELL_VENDORID:
            continue
        if device.idProduct != DELL_PRODUCTID:
            continue
        dev = device
        break

print device

And i got :

<usb.Device object at 0x1b22650>

Ok, i found my USB device ! It’s the most easy to do.
I’ve spend few hours to check how to send the same message as my previous window seven capture.
2 days later (today so), i finally found the command to start talking to my device ! (and also understand that only one command is needed, no need to do all the same as window are doing.)

# initialization
handle = dev.open()
handle.detachKernelDriver(1)
handle.claimInterface(0)

# read !
while True:
    try:
        buffer = handle.bulkRead(0x81, 1024)
        print buffer
    except:
        # no data
        continue

Gotcha ! I got blob from 460 to 887 length. Just need to found the point position in 🙂

3. Cry cry cry.

After some conversion, the first 32o part, except some of them, are static. All data after are moving a lot.
The bytes 10 and 18 changes every “seconds”, but not really. Weird.

So ok ok, what can i do for data part ?
I’ve tryed to :

  • check if it’s a HID message (the whole data, and the moving data part…) => failed
  • check if it’s an HID structure => failed
  • read the NextWindow api, tryied to found a common scheme => failed
  • trying to found myself float with cursor position => failed

Let’s start about my last test :

    # start from the bytes 32.
    s = 32
    # most of packet have 384 bytes, try to read them.
    b = buffer[s:s+384]
    if len(buffer) < 384:
        print 'packet too small'
    # convert to float
    o = struct.unpack('f' * (384 / 4), ''.join(map(chr, b)))

    print o

Ok, lot of 0.0, -0.0, and lot of non readable value.
Let’s filters them :

    for i in xrange(len(o)):
        od = o[i]
        if (od < 65535 and od > 0.0001) or (od > -65535 and od < -0.0001):
            print i, s+i*4, len(buffer), '%-6.4f' % od

And we got the output :

20 112 845 0.0009
21 116 845 0.0037
22 120 845 0.0146
23 124 845 0.0586
24 128 845 0.2344
25 132 845 0.9375
26 136 845 3.7501
27 140 845 15.0003
28 144 845 60.0010
29 148 845 240.0040
30 152 845 960.0161
31 156 845 3840.0642
32 160 845 15360.2568
33 164 845 61441.0273
59 268 845 0.0002
90 392 845 0.0002

The index 20-32 are showed every seconds. Mmh, same as the first thing in the static header.
To removing the noise, and check only the position value, i decided to remove all 20-32, plus some others.

And… i discovering something big.
When i moving my finger from left to right… value changes yes. But also the Index !
At left, the index is near 0, at right, the index is near 80.
Is the position x/y is moving inside the data structure ? How is possible ???

4. Get a light, and discover the madness.

On the NextWindow paper, they said it’s optical. They talk about occlusion, and unseen touch, with a scheme of … sensor waveform.

So, i think that data part is sort-of raw value of their whole line of sensor.
GOD ! Do i need to check myself where touchs are ? No… :/

I need to sleep, and let’s try later to understand waveform (and correctly locate them in the data part), and try to convert information into a touch… !