<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>linux — jd:/dev/blog</title><description>Posts tagged &quot;linux&quot; on jd:/dev/blog.</description><link>https://julien.danjou.info/</link><item><title>Using Gnocchi with Docker</title><link>https://julien.danjou.info/blog/using-gnocchi-with-docker/</link><guid isPermaLink="true">https://julien.danjou.info/blog/using-gnocchi-with-docker/</guid><description>I&apos;ve recently started to look into Docker to build images ready to be used with Gnocchi in it. I found it would be a great way to distribute a working instance of Gnocchi.</description><pubDate>Thu, 17 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve recently started to look into Docker to build images ready to be used with &lt;a href=&quot;http://gnocchi.xyz&quot;&gt;Gnocchi&lt;/a&gt; in it. I found it would be a great way to distribute a working instance of Gnocchi.&lt;/p&gt;
&lt;p&gt;To this end, we created the &lt;a href=&quot;https://github.com/gnocchixyz/gnocchi-docker&quot;&gt;gnocchi-docker&lt;/a&gt; repository on GitHub. It contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a 11 lines long (only!) &lt;a href=&quot;https://github.com/gnocchixyz/gnocchi-docker/blob/master/gnocchi/Dockerfile&quot;&gt;Dockerfile&lt;/a&gt; to build a Linux image containing Gnocchi;&lt;/li&gt;
&lt;li&gt;a &lt;a href=&quot;https://github.com/gnocchixyz/gnocchi-docker/tree/master/grafana&quot;&gt;Dockerfile&lt;/a&gt; to create a &lt;a href=&quot;https://grafana.com/&quot;&gt;Grafana&lt;/a&gt; image that will use Gnocchi as datasource (preconfigured);&lt;/li&gt;
&lt;li&gt;a &lt;a href=&quot;https://github.com/gnocchixyz/gnocchi-docker/blob/master/collectd/Dockerfile&quot;&gt;Dockerfile&lt;/a&gt; to create a &lt;a href=&quot;http://collectd.org&quot;&gt;collectd&lt;/a&gt; image that gather various metrics for your container in order to feed Gnocchi and have something to display in Grafana;&lt;/li&gt;
&lt;li&gt;a &lt;a href=&quot;https://github.com/gnocchixyz/gnocchi-docker/blob/master/docker-compose.yaml&quot;&gt;docker-compose file&lt;/a&gt; that orchestrates and runs those containers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don&apos;t know &lt;a href=&quot;https://docs.docker.com/compose/&quot;&gt;docker-compose&lt;/a&gt;, it&apos;s a tool to define and run applications using multiple containers. This is very handy in our case, as we need to start a few services, and therefore a few containers, to have our whole stack running.&lt;/p&gt;
&lt;p&gt;If you just want to use and run Gnocchi in a snap using this, it&apos;s easy. First clone the repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/gnocchixyz/gnocchi-docker.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, just ask docker-compose to start your stack of containers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd gnocchi-docker
$ docker-compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the first run, &lt;code&gt;docker-compose&lt;/code&gt; will build the various images (this should take only a few minutes) and then will start them.&lt;/p&gt;
&lt;p&gt;Once everything is started, you can connect to Grafana by typing the URL &lt;code&gt;http://&amp;lt;ip of your docker server&amp;gt;:3000&lt;/code&gt; in your browser and using &quot;admin&quot; as username and &quot;password&quot; as password. Just click on the dashboard entitled &quot;Gnocchi&quot; and wait a few minutes: you will see the chart being drawn in real time!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/gnocchi-docker-grafana-screenshot.png&quot; alt=&quot;gnocchi-docker-grafana-screenshot&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The data fed into Gnocchi come from the &lt;code&gt;collectd&lt;/code&gt; container, which gathers various metrics (CPU, network interface statistics, etc).&lt;/p&gt;
&lt;p&gt;You can then edit the docker files as you like to add new features or test your code. The files are also a good basis if you want to deploy Gnocchi in production running Docker!&lt;/p&gt;
&lt;p&gt;If you want to access and play with Gnocchi in command line, just install &lt;a href=&quot;https://pypi.python.org/pypi/gnocchiclient&quot;&gt;gnocchiclient&lt;/a&gt; and do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ export GNOCCHI_ENDPOINT=http://`docker-machine ip`:8041
$ gnocchi resource list
+----------+----------+------------+---------+----------------------+------------+----------+----------------+--------------+---------+
| id       | type     | project_id | user_id | original_resource_id | started_at | ended_at | revision_start | revision_end | creator |
+----------+----------+------------+---------+----------------------+------------+----------+----------------+--------------+---------+
| c31e4adc | collectd | None       | None    | collectd:fake-phy-   | 2017-08-17 | None     | 2017-08-17T12: | None         | admin   |
| -2cff-5f |          |            |         | host-719acbad336c    | T12:20:27. |          | 20:27.643790+0 |              |         |
| 78-8206- |          |            |         |                      | 643778+00: |          | 0:00           |              |         |
| f5ca66e4 |          |            |         |                      | 00         |          |                |              |         |
| 6cce     |          |            |         |                      |            |          |                |              |         |
+----------+----------+------------+---------+----------------------+------------+----------+----------------+--------------+---------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can now have fun creating new resources and metrics!&lt;/p&gt;
&lt;p&gt;Feel free to contribute patches to &lt;a href=&quot;http://github.com/gnocchixyz/gnocchi-docker&quot;&gt;the GitHub project&lt;/a&gt; too, obviously!&lt;/p&gt;
</content:encoded><category>gnocchi</category><category>linux</category></item><item><title>Logitech Unifying devices support in UPower</title><link>https://julien.danjou.info/blog/logitech-unifying-upower/</link><guid isPermaLink="true">https://julien.danjou.info/blog/logitech-unifying-upower/</guid><description>A few months ago, I wrote about my reverse engineering attempt to Logitech Unifying devices . Back then, I concluded my post with big hopes on the future after receiving a document with some part of t</description><pubDate>Fri, 16 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A few months ago, &lt;a href=&quot;https://julien.danjou.info/blog/logitech-k750-linux-support&quot;&gt;I wrote about my reverse engineering attempt to Logitech Unifying devices&lt;/a&gt;. Back then, I concluded my post with big hopes on the future after receiving a document with some part of the specification of the HID++ 2.0 from Logitech.&lt;/p&gt;
&lt;p&gt;A couple of weeks ago, some of my summer work has been merged to &lt;a href=&quot;http://upower.freedesktop.org/&quot;&gt;UPower&lt;/a&gt;, adding battery support for some Logitech devices.&lt;/p&gt;
&lt;h2&gt;HID++&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/m705.jpg&quot; alt=&quot;m705&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As I discovered late in my first reverse engineering attempt, Logitech developed a custom HID protocol named HID++. This protocol exists in two versions, 1.0 and 2.0. Some devices talk with version 1 of the protocol (like my M705 mouse) and some others talk with version 2 of the protocol (like my K750 keyboard).&lt;/p&gt;
&lt;p&gt;Recently, I&apos;ve been able to be in touch with a Logitech engineer who worked on the Linux support for the Unifying receiver, and he has been really helpful and exposed me some details about this protocol.&lt;/p&gt;
&lt;p&gt;Logitech made the decision to publish their HID++ specification publicly about a year ago, but still didn&apos;t do it. The internal review needed to publish such documents hasn&apos;t be done yet. The &lt;a href=&quot;http://6xq.net/git/lars/lshidpp.git/plain/doc/logitech_hidpp_2.0_specification_draft_2012-06-04.pdf&quot;&gt;only published draft&lt;/a&gt; is just an extract of the specification, with even some typo in it as I discovered.&lt;/p&gt;
&lt;p&gt;Some &lt;a href=&quot;https://drive.google.com/?tab=mo&amp;amp;pli=1&amp;amp;authuser=0#folders/0BxbRzx7vEV7eWmgwazJ3NUFfQ28&quot;&gt;other documents&lt;/a&gt; have been recently published, but I didn&apos;t have the time to review them. They contains HID++ 1.0 specifications and some details I asked for about the K750 keyboard.&lt;/p&gt;
&lt;h2&gt;UPower support&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/upower-1.png&quot; alt=&quot;upower-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It took me sometime to get a full understanding of the protocol, its different version etc. After reverse engineering my K750 keyboard, I&apos;ve also reverse engineered the data stream used to get my M705 mouse battery status. I&apos;ve also received some information about the HID++ 1.0 protocol, so I&apos;ve been able to discover a bit more on what the packets mean. Most of my discoveries are now used to do proper &lt;code&gt;#define&lt;/code&gt; in &lt;a href=&quot;http://cgit.freedesktop.org/upower/tree/src/linux/up-device-lg-unifying.c&quot;&gt;&lt;code&gt;up-lg-unifying.c&lt;/code&gt;&lt;/a&gt; so the code makes more sense.&lt;/p&gt;
&lt;p&gt;My &lt;a href=&quot;http://cgit.freedesktop.org/upower/commit/?id=2f03ad62b520fc5c02e3ff9eb5bffc4275eb88dc&quot;&gt;first patch&lt;/a&gt; implements a new property for UPower devices, named &lt;em&gt;luminosity&lt;/em&gt;, that use with K750 keyboard to report the light level received. The &lt;a href=&quot;http://cgit.freedesktop.org/upower/commit/?id=95184593504bca5240ecd296db98954decd2c5a5&quot;&gt;second patch&lt;/a&gt; add support for Logitech Unifying devices (over USB only) and should work with at least Logitech M705 and K750 devices. This should be available with the next version of UPower, which should be 0.9.19.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/gnome-power-statistics-k750.png&quot; alt=&quot;gnome-power-statistics-k750&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So far, Logitech has been kind enough to help me understanding part of the protocol and even sent me a few devices so I can play and test my work with them. Unfortunately, this will probably requires some work and time, and so far Logitech was not able to help with that.&lt;/p&gt;
&lt;p&gt;There should be enough information out there to at least add support for battery to HID++ 2.0 devices, and probably a few other things too. I hope I&apos;d get the time do this at some point, but feel free to beat me in this race!&lt;/p&gt;
</content:encoded><category>x11</category><category>linux</category></item><item><title>Sony Vaio Z Debian Linux support</title><link>https://julien.danjou.info/blog/sony-vaio-svz13-linux/</link><guid isPermaLink="true">https://julien.danjou.info/blog/sony-vaio-svz13-linux/</guid><description>I had to install Debian Wheezy on a brand new Sony Vaio Z laptop with the new Ivy Bridge architecture (SVZ1311C5E). I&apos;ll talk about this here, because it&apos;s always nice to know that new hardware works</description><pubDate>Sat, 11 Aug 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I had to install Debian Wheezy on a brand new Sony Vaio Z laptop with the new Ivy Bridge architecture (SVZ1311C5E). I&apos;ll talk about this here, because it&apos;s always nice to know that new hardware works quite fine (or not) under Debian.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/sony-vaio-z-2012-1.jpg&quot; alt=&quot;sony-vaio-z-2012-1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The laptop is delivered with Window 7, which I decided to remove entirely anyway, and replace with Debian. I&apos;ve installed it with Linux 3.2 and then ran Linux 3.4, 3.5 and 3.6-rc1.&lt;/p&gt;
&lt;h2&gt;USB booting&lt;/h2&gt;
&lt;p&gt;Don&apos;t ask me why, nor an Ubuntu or Debian USB installation booted, blocked at SYSLINUX at best, or at a black screen. This does not work. I had to use PXE to install Debian.&lt;/p&gt;
&lt;h2&gt;Storage&lt;/h2&gt;
&lt;p&gt;The only thing that can be surprising, is that the 128 GB SSD storage is actually made of 2 64 GB Samsung SSD aggregated in a RAID 0 using &lt;em&gt;&lt;a href=&quot;http://www.intel.com/p/en_US/support/highlights/chpsts/imsm/&quot;&gt;Intel Rapid Storage Technology&lt;/a&gt;&lt;/em&gt;, previously known as &lt;em&gt;Intel Matrix&lt;/em&gt;. This is supported by Linux using the &lt;em&gt;dm-raid&lt;/em&gt; module. So this is a fake RAID, and you anyway can see the both drives as &lt;em&gt;sda&lt;/em&gt; and &lt;em&gt;sdb&lt;/em&gt; under Linux.&lt;/p&gt;
&lt;p&gt;Unfortunately, this kind of RAID is not supported correctly by GRUB, and I was unable to install it this way. Therefore, I decided to remove entirely this fake RAID (which is possible via the BIOS) and use a Linux software &lt;em&gt;md&lt;/em&gt; RAID 0 instead, plus crypto on top of it. That I know well and I trust. :)&lt;/p&gt;
&lt;h2&gt;Graphics&lt;/h2&gt;
&lt;p&gt;The Intel HD Graphics 4000 works fine. I&apos;m alsmo using the HDMI output, which works fine. There&apos;s some GPU hanging (as seen on screen and in kernel logs) in Linux up to 3.4, but with versions 3.5 and above, I didn&apos;t see any problem so far.&lt;/p&gt;
&lt;h2&gt;Sound&lt;/h2&gt;
&lt;p&gt;The Intel HDA sound card works pretty well, both for playing and recording. The main problem is that I hear a constant noise on the speakers, but tweaking the ALSA mixers ends it at some point. There&apos;s still probably a bug, not yet resolved in Linux 3.6-rc1.&lt;/p&gt;
&lt;h2&gt;Keyboard&lt;/h2&gt;
&lt;p&gt;The keyboard works fine, and the back-light too, via the &lt;em&gt;sony-laptop&lt;/em&gt; kernel module. Wonderful.&lt;/p&gt;
&lt;h2&gt;Touchpad&lt;/h2&gt;
&lt;p&gt;Touchpad works fine.&lt;/p&gt;
&lt;h2&gt;Fingerprint&lt;/h2&gt;
&lt;p&gt;It does not work, and is not supported according to my research. Not that I care about, but don&apos;t count on it. It&apos;s an AuthenTec AES1660.&lt;/p&gt;
&lt;h2&gt;Webcam&lt;/h2&gt;
&lt;p&gt;It works perfectly.&lt;/p&gt;
&lt;h2&gt;USB&lt;/h2&gt;
&lt;p&gt;Well, USB 3.0 does not work. I had to disable XHCI in the BIOS and use the 2 ports as standard USB 2.0, otherwise I would just get errors from the kernel. Still not working with Linux 3.6-rc1, and I&apos;ve no clue to debug, and do not use USB 3.0 yet, so…&lt;/p&gt;
&lt;h2&gt;WiFi&lt;/h2&gt;
&lt;p&gt;The WiFi module (based on iwlwifi) works fine. The only problem with NetworkManager is that the &lt;em&gt;sony-laptop&lt;/em&gt; offers a second rfkill switch and NM does not know how to handle it correctly. &lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=680632&quot;&gt;A bug is opened about this&lt;/a&gt; and I hope to be able to write a patch or something at some point. Also, there seems to be some quality issue with the &lt;em&gt;iwlwifi&lt;/em&gt; driver and 802.11n at this point. I&apos;m losing connection quite often when the signal drops below 40 %. Loading the module with &lt;em&gt;11n_disable=1&lt;/em&gt; helps a lot.&lt;/p&gt;
&lt;h2&gt;Ethernet&lt;/h2&gt;
&lt;p&gt;The gigabit Realtek Ethernet controller works perfectly.&lt;/p&gt;
&lt;h2&gt;Card reader&lt;/h2&gt;
&lt;p&gt;Works perfectly.&lt;/p&gt;
</content:encoded><category>debian</category><category>linux</category></item><item><title>Logitech K750 keyboard and Unifying Receiver Linux support</title><link>https://julien.danjou.info/blog/logitech-k750-linux-support/</link><guid isPermaLink="true">https://julien.danjou.info/blog/logitech-k750-linux-support/</guid><description>A year ago, I bought a Logitech Wireless Solar Keyboard K750. I&apos;m particularly picky on keyboards, but this one is good.</description><pubDate>Mon, 09 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A year ago, I bought a &lt;a href=&quot;http://www.logitech.com/keyboards/keyboards/k750-keyboard&quot;&gt;Logitech Wireless Solar Keyboard K750&lt;/a&gt;. I&apos;m particularly picky on keyboards, but this one is good. It has an incredible useful feature: while being wireless, it has no need for disposable or rechargeable batteries, it uses solar power!&lt;/p&gt;
&lt;p&gt;My problem is that there&apos;s obviously no way to know the battery status from Linux, the provided application only working on Windows.&lt;/p&gt;
&lt;p&gt;And one dark night, while fragging on QuakeLive, my keyboard stopped working: it had no battery left. This activity being quite energy consuming, it emptied the whole battery.&lt;/p&gt;
&lt;p&gt;Someone should write code to get the battery status and light meter from Linux: challenge accepted!&lt;/p&gt;
&lt;h2&gt;How the keyboard works&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/logitech-unifying.jpg&quot; alt=&quot;logitech-unifying&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This keyboard, like many of the new wireless devices from Logitech, uses the &lt;em&gt;Unifying&lt;/em&gt; interface. It&apos;s an USB receiver that can be attached up to 6 differents devices (mouse, keyboards…). On old Linux kernel, the &lt;em&gt;Unifying&lt;/em&gt; receiver is recognized as only one keyboard and/or one mouse device.&lt;/p&gt;
&lt;p&gt;Recently, a driver called &lt;em&gt;hid-logitech-dj&lt;/em&gt; has been added to the Linux kernel. With this driver, each device attached to the receiver is recognized as one different device.&lt;/p&gt;
&lt;h2&gt;What the Logitech application does&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://julien.danjou.info/content/images/03/logitech-solar-app.png&quot; alt=&quot;logitech-solar-app&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The Logitech application under Windows works that way: you launch it, and it displays the battery charge level. On the keyboard, there&apos;s a special &quot;light&quot; button (up right). When pressed, a LED will light up on the keyboard: green if the keyboard is receiving enough light and is charging, red if the keyboard does not receive enough light and is therefore discharging. Pushing this same button while the application is running will makes the light meter activated: the application will tell you how much &lt;a href=&quot;http://en.wikipedia.org/wiki/Lux&quot;&gt;lux&lt;/a&gt; your keyboard is receiving.&lt;/p&gt;
&lt;h2&gt;Let&apos;s reverse engineer this&lt;/h2&gt;
&lt;p&gt;As far as I know, there&apos;s nothing in the USB HID protocol that handles this kind of functionality (battery status, light meter…) in a standard way. So the first task to accomplish is, unfortunately, to reverse engineer the program.&lt;/p&gt;
&lt;p&gt;I discovered a bit too late that &lt;a href=&quot;http://www.youtube.com/watch?v=jMf55KVDPaE&quot;&gt;Drew Fisher did a good presentation on USB reverse engineering at 28c3&lt;/a&gt;. You might want to take a look at it if you want to reverse engineer on USB. I did not need it, but I learned a few things.&lt;/p&gt;
&lt;p&gt;Anyway, my plan was the following: run the Logitech application inside a virtual machine running Windows, give it direct access to the USB keyboard, and sniff what happens on the USB wire.&lt;/p&gt;
&lt;p&gt;To achieve that, you need a virtual machine emulator that can do USB pass-through. Both &lt;a href=&quot;http://www.linux-kvm.org/page/Main_Page&quot;&gt;KVM&lt;/a&gt; and &lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;VirtualBox&lt;/a&gt; can do that, but VirtualBox works much better with USB and allow hot(un)plugging of devices, so I used it.&lt;/p&gt;
&lt;p&gt;To sniff what happens on the USB, you need to load the &lt;em&gt;usbmon&lt;/em&gt; Linux kernel module. Simply doing &lt;code&gt;modprobe usbmon&lt;/code&gt; will work. You can then use &lt;a href=&quot;http://www.wireshark.org/&quot;&gt;Wireshark&lt;/a&gt; which know how to use &lt;em&gt;usbmon&lt;/em&gt; devices and understand the USB protocol.&lt;/p&gt;
&lt;h3&gt;USB stuff you need to know&lt;/h3&gt;
&lt;p&gt;You don&apos;t need to know much about USB to understand what I&apos;ll write about below, but for the sake of comprehensibility I&apos;ll write a couple of things here before jumping in.&lt;/p&gt;
&lt;p&gt;To communicate with an USB device, we communicate with one of its &lt;em&gt;endpoints&lt;/em&gt;. Endpoints are regrouped into an &lt;em&gt;interface&lt;/em&gt;. Interfaces are regrouped into a &lt;em&gt;configuration&lt;/em&gt;. A device might contains one or several configurations.&lt;/p&gt;
&lt;p&gt;There&apos;s also several types of packets in the USB wire protocol, and at least two of them interest us there, they are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Interrupt packets, a packet send spontaneously;&lt;/li&gt;
&lt;li&gt;Controls packets, used for command and status operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of this and more is well (and better) explained in the &lt;a href=&quot;http://lwn.net/images/pdf/LDD3/ch13.pdf&quot;&gt;chapter 13&lt;/a&gt; of &lt;a href=&quot;http://lwn.net/Kernel/LDD3/&quot;&gt;Linux Device Drivers, Third Edition&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Sniffed data&lt;/h3&gt;
&lt;p&gt;Once everything was set-up, I ran my beloved Wireshark. There&apos;s a an URB of type &lt;em&gt;interrupt&lt;/em&gt; sent each time you press any key with some data in it. Therefore I advise you to plug another keyboard (or use the laptop keyboard if you&apos;re doing this on a laptop), otherwise you&apos;ll get crazy trying to sniff the keyboard you&apos;re typing on.&lt;/p&gt;
&lt;p&gt;At this point, just launching the application does a bunch of USB traffic. Pressing the &quot;light&quot; button on the keyboard makes even more USB packets coming in and out. Here&apos;s the interesting packets that I noticed once I excluded the noise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When pressing the &quot;light&quot; button, an URB of type &lt;em&gt;interrupt&lt;/em&gt; is sent by the keyboard to the computer;&lt;/li&gt;
&lt;li&gt;An URB &lt;em&gt;control&lt;/em&gt; packet is sent by the computer to the keyboard in response;&lt;/li&gt;
&lt;li&gt;Regularly URB &lt;em&gt;interrupt&lt;/em&gt; packets are sent just after.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With all this, the next step was clear: understand the packets and reproduce that exchange under Linux.&lt;/p&gt;
&lt;h3&gt;What the packets mean&lt;/h3&gt;
&lt;h4&gt;The &quot;go for the light meter&quot; packet&lt;/h4&gt;
&lt;p&gt;The packet sent from the computer to the keyboard is the following.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Frame 17: 71 bytes on wire (568 bits), 71 bytes captured (568 bits)
    Frame Length: 71 bytes (568 bits)
    Capture Length: 71 bytes (568 bits)
USB URB
    URB id: 0xffff880161997240
    URB type: URB_SUBMIT (&apos;S&apos;)
    URB transfer type: URB_CONTROL (0x02)
    Endpoint: 0x00, Direction: OUT
        0... .... = Direction: OUT (0)
        .000 0000 = Endpoint value: 0
    Device: 6
    URB bus id: 1
    Device setup request: relevant (0)
    Data: present (0)
    URB sec: 1340124450
    URB usec: 495643
    URB status: Operation now in progress (-EINPROGRESS) (-115)
    URB length [bytes]: 7
    Data length [bytes]: 7
    [Response in: 18]
    [bInterfaceClass: HID (0x03)]
    URB setup
        bmRequestType: 0x21
            0... .... = Direction: Host-to-device
            .01. .... = Type: Class (0x01)
            ...0 0001 = Recipient: Interface (0x01)
    bRequest: SET_REPORT (0x09)
    wValue: 0x0210
        ReportID: 16
        ReportType: Output (2)
    wIndex: 2
    wLength: 7
0000  40 72 99 61 01 88 ff ff 53 02 00 06 01 00 00 00   @r.a....S.......
0010  22 ad e0 4f 00 00 00 00 1b 90 07 00 8d ff ff ff   &quot;..O............
0020  07 00 00 00 07 00 00 00 21 09 10 02 02 00 07 00   ........!.......
0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0040  10 01 09 03 78 01 00                              ....x..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What&apos;s here interesting is the last part representing the data. &lt;em&gt;wLength&lt;/em&gt; says that the length of the data is 7 bytes, so let&apos;s take a look at those 7 bytes: &lt;code&gt;10 01 09 03 78 01 00&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Well, actually, you can&apos;t decode them like that, unless you&apos;re a freak or a Logitech engineer. And I have actually no idea what they mean. But sending this to the keyboard will trigger an interesting thing: the keyboard will start sending URB interrupt with some data without you pressing any more key.&lt;/p&gt;
&lt;h4&gt;The &quot;light meter and battery values&quot; packet&lt;/h4&gt;
&lt;p&gt;This is most interesting packet. This is the one sent by the keyboard to the host and that contains the data we want to retrieve.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Frame 1467: 84 bytes on wire (672 bits), 84 bytes captured (672 bits)
    Frame Length: 84 bytes (672 bits)
    Capture Length: 84 bytes (672 bits)
USB URB
    URB id: 0xffff88010c43c380
    URB type: URB_COMPLETE (&apos;C&apos;)
    URB transfer type: URB_INTERRUPT (0x01)
    Endpoint: 0x83, Direction: IN
        1... .... = Direction: IN (1)
        .000 0011 = Endpoint value: 3
    Device: 2
    URB bus id: 6
    Device setup request: not relevant (&apos;-&apos;)
    Data: present (0)
    URB sec: 1334953309
    URB usec: 728740
    URB status: Success (0)
    URB length [bytes]: 20
    Data length [bytes]: 20
    [Request in: 1466]
    [Time from request: 0.992374000 seconds]
    [bInterfaceClass: Unknown (0xffff)]
Leftover Capture Data: 1102091039000c061d474f4f4400000000000000

0000  80 c3 43 0c 01 88 ff ff 43 01 83 02 06 00 2d 00   ..C.....C.....-.
0010  5d c5 91 4f 00 00 00 00 a4 1e 0b 00 00 00 00 00   ]..O............
0020  14 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00   ................
0030  02 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00   ................
0040  11 02 09 10 39 00 0c 06 1d 47 4f 4f 44 00 00 00   ....9....GOOD...
0050  00 00 00 00                                       ....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This packets come in regularly (1 per second) on the wire for some time once you sent the &quot;go for the light meter&quot; packet. At one point they are emitted less often and do not contain the value for the light meter anymore, suggesting that the control packet sent earlier triggers the activation of the light meter for a defined period.&lt;/p&gt;
&lt;p&gt;Now you probably wonder where the data are in this. They&apos;re in the 20 bytes leftover in the capture data part, indicated by Wireshark, at the end of the packet: &lt;code&gt;11 02 09 10 39 00 0c 06 1d 47 4f 4f 44 00 00 00 00 00 00 00&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Fortunately, it was easy to decode. Knowing we&apos;re looking for 2 values (battery charge and light meter), we just need to observe and compare the packet emitted on the wire with the values displayed by the Logitech Solar App.&lt;/p&gt;
&lt;p&gt;To achieve this, I looked both at the &lt;em&gt;Logitech Solar App&lt;/em&gt; and &lt;em&gt;Wireshark&lt;/em&gt; while bringing more and more light near the keyboard, increasing the lux value received by the meter on the Solar App, and saw that the fields represented in blue (see below) where changing in Wireshark. Since 2 bytes were changing, I guessed that it was coded on 16 bits, and therefore it was easy to correlate the value with the Solar App.&lt;/p&gt;
&lt;p&gt;[ ....9....GOOD....... ]
11 02 09 10 39 00 0c 06 1d 47 4f 4f 44 00 00 00 00 00 00 00
4 bytes - 1 byte for battery charge - 2 bytes for light meter - 2 bytes - 4 bytes for GOOD - 7 bytes&lt;/p&gt;
&lt;p&gt;In this example, the battery has a charge of &lt;code&gt;0x39 = 57 %&lt;/code&gt; and the light meter receives &lt;code&gt;0x0c = 12 lux&lt;/code&gt; of light. It&apos;s basically dark, and that makes sense: it was night and the light was off in my office, the only light being the one coming from my screen.&lt;/p&gt;
&lt;p&gt;I&apos;ve no idea what the &lt;code&gt;GOOD&lt;/code&gt; part of the packet is about, but it&apos;s present in every packet and it&apos;s actually very handy to recognize such a packet. Therefore I&apos;m considering this as some sort of useful mark for now.&lt;/p&gt;
&lt;p&gt;For the other bytes, they were always the same (&lt;code&gt;0x11 0x2 0x9 0x10&lt;/code&gt; at the beginning, 7 times &lt;code&gt;0x00&lt;/code&gt; at the end). The 2 bytes between the light meter and GOOD probably mean something, but I&apos;ve no idea what for now.&lt;/p&gt;
&lt;h2&gt;Building our solar app&lt;/h2&gt;
&lt;p&gt;Now we&apos;ve enough information to build our own very basic solar application. We know how to triggers the light meter, and we know how to decode the packets.&lt;/p&gt;
&lt;p&gt;We&apos;re going to write a small application using &lt;a href=&quot;http://www.libusb.org/&quot;&gt;libusb&lt;/a&gt;. Here&apos;s a quick example. It&apos;s not perfect and does not check for error codes, be careful.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* Written by Julien Danjou &amp;lt;julien@danjou.info&amp;gt; in 2012 */

#include &amp;lt;linux/hid.h&amp;gt;

#include &amp;lt;libusb.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

int main(void)
{
    libusb_context *ctx;
    libusb_init(&amp;amp;ctx);
    libusb_set_debug(ctx, 3);

    /* Look at the keyboard based on vendor and device id */
    libusb_device_handle *device_handle = libusb_open_device_with_vid_pid(ctx, 0x046d, 0xc52b);

    fprintf(stderr, &quot;Found keyboard 0x%p\n&quot;, device_handle);

    libusb_device *device = libusb_get_device(device_handle);

    struct libusb_device_descriptor desc;

    libusb_get_device_descriptor(device, &amp;amp;desc);

    for(uint8_t config_index = 0; config_index &amp;lt; desc.bNumConfigurations; config_index++)
    {
        struct libusb_config_descriptor *config;

        libusb_get_config_descriptor(device, config_index, &amp;amp;config);

        /* We know we want interface 2 */
        int iface_index = 2;
        const struct libusb_interface *iface = &amp;amp;config-&amp;gt;interface[iface_index];

        for (int altsetting_index = 0; altsetting_index &amp;lt; iface-&amp;gt;num_altsetting; altsetting_index++)
        {
            const struct libusb_interface_descriptor *iface_desc = &amp;amp;iface-&amp;gt;altsetting[altsetting_index];

            if (iface_desc-&amp;gt;bInterfaceClass == LIBUSB_CLASS_HID)
            {
                libusb_detach_kernel_driver(device_handle, iface_index);
                libusb_claim_interface(device_handle, iface_index);

                unsigned char ret[65535];

                unsigned char payload[] = &quot;\x10\x01\x09\x03\x78\x01\x00&quot;;

                if(libusb_control_transfer(device_handle,
                                           LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
                                           HID_REQ_SET_REPORT,
                                           0x0210, iface_index, payload, sizeof(payload) - 1, 10000))
                {
                    int actual_length = 0;

                    while(actual_length != 20 || strncmp((const char *) &amp;amp;ret[9], &quot;GOOD&quot;, 4))
                        libusb_interrupt_transfer(device_handle,
                                                  iface_desc-&amp;gt;endpoint[0].bEndpointAddress,
                                                  ret, sizeof(ret), &amp;amp;actual_length, 100000);

                    uint16_t lux = ret[5] &amp;lt;&amp;lt; 8 | ret[6];

                    fprintf(stderr, &quot;Charge: %d %%\nLight: %d lux\n&quot;, ret[4], lux);
                }

                libusb_release_interface(device_handle, iface_index);
                libusb_attach_kernel_driver(device_handle, iface_index);
            }
        }
    }

    libusb_close(device_handle);
    libusb_exit(ctx);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What the program is doing is the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Request for the Unifying Receiver device based on vendor and product ID&lt;/li&gt;
&lt;li&gt;Get the HID interface&lt;/li&gt;
&lt;li&gt;Detach the HID interface from the kernel driver&lt;/li&gt;
&lt;li&gt;Claim the interface&lt;/li&gt;
&lt;li&gt;Send a control packets, were parameters are defined using the same data we captured earlier&lt;/li&gt;
&lt;li&gt;Read interrupt packets coming in until we receive one we recognize (length 20 containing the &quot;GOOD&quot; string)&lt;/li&gt;
&lt;li&gt;Decode the content (battery charge &amp;amp; light meter)&lt;/li&gt;
&lt;li&gt;Release the interface&lt;/li&gt;
&lt;li&gt;Reattach the kernel driver to the interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This gives the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Found keyboard 0x0x24ec8e0
Charge: 64 %
Light: 21 lux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Challenge accomplished!&lt;/p&gt;
&lt;h2&gt;To be continued&lt;/h2&gt;
&lt;p&gt;Unfortunately, this approach has at least one major drawback. We have to disconnect the &lt;em&gt;Logitech Unifying Receiver&lt;/em&gt; from the kernel. That means that while we&apos;re waiting for the packet, we&apos;re dropping packets corresponding to other events from every connected device (key presses, pointer motions…).&lt;/p&gt;
&lt;p&gt;In order to solve that, I sent a request for help on the &lt;a href=&quot;http://vger.kernel.org/vger-lists.html#linux-input&quot;&gt;linux-input&lt;/a&gt; mailing list. That way, I learned that Logitech is actually using the HID++ protocol to communicate with the devices using the Unifying Receiver. &lt;a href=&quot;http://6xq.net&quot;&gt;Lars-Dominik Braun&lt;/a&gt; managed to get the HID++ specifications from Logitech and &lt;a href=&quot;http://6xq.net/git/lars/lshidpp.git/plain/doc/logitech_hidpp_2.0_specification_draft_2012-06-04.pdf&quot;&gt;published them&lt;/a&gt; with their authorization.&lt;/p&gt;
&lt;p&gt;This opens a whole new world. With that document, I may be able to understand the part I reverse engineered and convert this to a more useful and generic library using the hidraw interface (so we don&apos;t have to disconnect the devices from the kernel driver).&lt;/p&gt;
</content:encoded><category>linux</category></item><item><title>Porting D-Bus to XCB: story of a failure</title><link>https://julien.danjou.info/blog/porting-dbus-on-xcb/</link><guid isPermaLink="true">https://julien.danjou.info/blog/porting-dbus-on-xcb/</guid><description>Even if I recently stated I lost some of my faith in XCB, I still sometimes hack things to add support for it.</description><pubDate>Thu, 29 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Even if &lt;a href=&quot;https://julien.danjou.info/blog/thoughts-and-rambling-on-the-x-protocol&quot;&gt;I recently stated I lost some of my faith&lt;/a&gt; in &lt;a href=&quot;http://xcb.freedesktop.org&quot;&gt;XCB&lt;/a&gt;, I still sometimes hack things to add support for it.&lt;/p&gt;
&lt;p&gt;These last days, I&apos;ve worked on a &lt;a href=&quot;http://dbus.freedesktop.org&quot;&gt;D-Bus&lt;/a&gt; port from Xlib to XCB. The port was quite straight forward, since there&apos;s only a little piece of D-Bus using X, which is &lt;code&gt;dbus-launch&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I though D-Bus was a good candidate, since it&apos;s part of the &lt;a href=&quot;http://www.freedesktop.org&quot;&gt;Freedesktop&lt;/a&gt; initiative. Therefore, I was expecting a warm welcome and some enthusiasm from a fellow project.&lt;/p&gt;
&lt;p&gt;My contribution got one useful review, and a &lt;a href=&quot;http://lists.freedesktop.org/archives/dbus/2010-July/013185.html&quot;&gt;cold reply from Thiago Macieira&lt;/a&gt; (a &lt;a href=&quot;http://www.kde.org&quot;&gt;KDE&lt;/a&gt;/&lt;a href=&quot;http://qt.nokia.com&quot;&gt;Qt&lt;/a&gt;/&lt;a href=&quot;http://www.nokia.com&quot;&gt;Nokia&lt;/a&gt; developer):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No, sorry, I don&apos;t agree..&lt;br /&gt;
I&apos;ve just checked and my Solaris machine doesn&apos;t have XCB.&lt;br /&gt;
Please do not remove the X11 code. You may &lt;em&gt;add&lt;/em&gt; the XCB code, but you cannot remove the X11 code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is not really the kind of answer I expected, actually. I then reworked the code to &lt;a href=&quot;http://lists.freedesktop.org/archives/dbus/2010-July/013192.html&quot;&gt;please Thiago&lt;/a&gt;, and added some &lt;em&gt;#ifdef&lt;/em&gt; to add XCB support to D-Bus, with a fallback to libx11 where XCB would not be available.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://lists.freedesktop.org/archives/dbus/2010-July/013196.html&quot;&gt;Havoc Pennington replied&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given that libX11 now uses xcb as backend, I don&apos;t understand the&lt;br /&gt;
value of porting to use libxcb directly when there isn&apos;t an issue of&lt;br /&gt;
round trips or other stuff. It will just make #ifdef hell, while the&lt;br /&gt;
X11 API is an API that works on both xcb and non-xcb platforms.&lt;br /&gt;
Maybe people should be thinking about porting xcb to non-Linux&lt;br /&gt;
platforms? The X protocol should be the same on other UNiX, so xcb in&lt;br /&gt;
theory ought to work fine if you just compiled it on Solaris/BSD, same&lt;br /&gt;
as GTK or dbus or Qt would work fine.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The last part &quot;Maybe people should be thinking about porting xcb to non-Linux platforms?&quot; is still unclear to me, even though &lt;a href=&quot;http://lists.freedesktop.org/archives/dbus/2010-July/013197.html&quot;&gt;I asked Havoc to explain what he meant&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, &lt;a href=&quot;http://lists.freedesktop.org/archives/dbus/2010-July/013198.html&quot;&gt;Thiago refused to merge the patch&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[…] thanks for the patch, but like Havoc I am unsure of the value. We can&apos;t&lt;br /&gt;
drop the X11 codepaths now because too many systems exist without&lt;br /&gt;
XCB. Adding the XCB codepaths only made it more complex, even though you did a good job.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I can&apos;t disagree with that conclusion: using both XCB and X11 make the code unreadable for little gain. That&apos;s why I did replace libx11 by XCB directly in the first version of the patch. On the other hand, D-Bus people does not seems to really care about making their software evolve in the right direction, even if that requires users to upgrade their systems.&lt;/p&gt;
&lt;p&gt;I think D-Bus using and depending on XCB would have been a good point to push adoption of XCB. Unfortunately, it seems you can&apos;t even rely of projects of the same initiative (i.e. Freedesktop) to work together to make things a little bit better.&lt;/p&gt;
&lt;p&gt;After 5 years of existence, XCB is still not so obvious to people, and making it adopt is going to be a challenge for the next years. The upside is that &lt;a href=&quot;http://www.x.org/wiki/Releases/7.6&quot;&gt;new X.org 7.6 will bring XCB with it&lt;/a&gt;, as part of the katamari.&lt;/p&gt;
</content:encoded><category>linux</category><category>x11</category></item><item><title>Unexpected VARMon new release</title><link>https://julien.danjou.info/blog/unexpected-varmon-new-release/</link><guid isPermaLink="true">https://julien.danjou.info/blog/unexpected-varmon-new-release/</guid><description>This has been 4 years since I released a new upstream release of VARMon, the DAC960 administration tool.</description><pubDate>Mon, 18 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This has been 4 years since I released a new upstream release of &lt;a href=&quot;http://github.com/jd/varmon&quot;&gt;VARMon&lt;/a&gt;, the DAC960 administration tool.&lt;/p&gt;
&lt;p&gt;There was a bug first discovered in &lt;a href=&quot;http://bugs.debian.org/401236&quot;&gt;#401236&lt;/a&gt;. It has been fixed in Debian with an ugly fix, which did not work finally for a long time. Recently &lt;a href=&quot;http://bugs.debian.org/491505&quot;&gt;#491505&lt;/a&gt; got opened too, which was the same as the previous one. But this time I got access to hardware, thanks to Christoph! And I finally fixed the bug. I&apos;ve even be able to test the fixes I wrote years ago for all of the compilation warnings.&lt;/p&gt;
&lt;p&gt;That&apos;s a shame that the problem was caused by dead code from the previous upstream, and that I did not realize that sooner. Kids, do not let dead debug code in your program at home.&lt;/p&gt;
&lt;p&gt;So I&apos;ve finally been able to release a new 1.2.1 version which maybe the last release for the next decade! ;-)&lt;/p&gt;
</content:encoded><category>linux</category><category>debian</category></item><item><title>ATL1E support in Linux 2.6.26-1</title><link>https://julien.danjou.info/blog/atl1e-support-in-2-6-26-1/</link><guid isPermaLink="true">https://julien.danjou.info/blog/atl1e-support-in-2-6-26-1/</guid><description>Ben Armstrong opened an ITP for the ATL1E NIC driver, which is found on some Asus EeePC laptops. So, as suggested by Maximilian Attems, I provided a clean patch for this driver, made from a.</description><pubDate>Thu, 31 Jul 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ben Armstrong opened an &lt;a href=&quot;http://bugs.debian.org/492029&quot;&gt;ITP for the ATL1E NIC driver&lt;/a&gt;, which is found on some Asus EeePC laptops. So, as suggested by Maximilian Attems, &lt;a href=&quot;http://lists.debian.org/debian-kernel/2008/07/msg00638.html&quot;&gt;I provided a clean patch for this driver&lt;/a&gt;, made from a cherry-pick from the linux-netdev 2.6.27 tree. It has been committed into the 2.6.26-1 Debian kernel, which will be furnished with Lenny.&lt;/p&gt;
&lt;p&gt;What&apos;s fun, is that in the mean time, I got a new computer at work. Wait, it&apos;s not fun yet. Because what I did not know is that it&apos;s made of an &lt;a href=&quot;http://asus.com/products.aspxl1=3&amp;amp;l2=11&amp;amp;l3=709&amp;amp;l4=0&amp;amp;model=2164&amp;amp;modelmenu=1&quot;&gt;Asus P5Q motherboard&lt;/a&gt; which runs a NIC needing the ATL1E driver (and now you see why it&apos;s fun).&lt;/p&gt;
&lt;p&gt;So I&apos;ve just upgraded to 2.6.26-1-amd64 and I&apos;m glad that my own work is useful to me (and will be probably be to others as well). :-)&lt;/p&gt;
</content:encoded><category>linux</category><category>debian</category></item></channel></rss>