Intel Dual Band Wireless-AC 3165 with Debian Jessie

Having bought a new laptop with an Intel Dual Band Wireless-AC 3165 adapter I had a few wifi troubles. It turned out that my kernel was a little too old for the driver; and I needed to update to at least 4.2 by adding jessie-backports to my sources.list; upgrading the kernel, and doing an apt-get install iwlwifi-firmware.

One further step was required – it turns out the iwlwifi driver loads firmware for the wireless adapter; and you need specific versions of the firmware. This was resolved by downloading the firmware for my adapter; and copying it into /lib/firmware.

So far so good! And then… a kernel upgrade. My wireless disappeared! It took a while but I finally figured it out by delving into the details of the firmware versioning. The iwlwifi driver defines an API; and only loads firmware for a span of versions. The version is listed in the filename; e.g. iwlwifi-7265D-14.ucode is a firmware supporting version 14 of the API. When the module loads it will try to load firmware versions in sequence – you can see this by typing sudo dmesg | grep iwlwifi which will give you an output like this:

[    2.164582] iwlwifi 0000:02:00.0: firmware: failed to load iwlwifi-7265D-23.ucode (-2)
[    2.164587] iwlwifi 0000:02:00.0: Direct firmware load for iwlwifi-7265D-23.ucode failed with error -2
[    2.164603] iwlwifi 0000:02:00.0: firmware: failed to load iwlwifi-7265D-22.ucode (-2)
[    2.164608] iwlwifi 0000:02:00.0: Direct firmware load for iwlwifi-7265D-22.ucode failed with error -2
[    2.188461] iwlwifi 0000:02:00.0: firmware: direct-loading firmware iwlwifi-7265D-21.ucode
[    2.188898] iwlwifi 0000:02:00.0: loaded firmware version 21.373438.0 op_mode iwlmvm

Here you can see the driver failing to load versions 23 and 22 – the files for which don’t exist – before succeeding with 21.

Unfortunately the latest version listed on the Intel website above is 14; and you can’t just rename these files – they have a header with the version which is checked. Just renaming the file only yielded an error message telling me Driver unable to support your firmware API. Driver supports 21, firmware is 14.

At this point I was starting to think the latest version was just too far ahead of the kernel; and was on the verge of trying to patch the firmware binary! Fortunately I did a bit more googling first, and managed to find an Intel support page that reveals later versions of the firmware can be downloaded directly from the linux-firmware repo. So by downloading version 21; and dropping it into /lib/firmware I was finally able to get wifi working with 4.9!

MQTT Quick start!

I’ve got a project in mind and I want to put a bit of pub/sub in it. It’s an “Internet of Things” (IOT) project and the idea is that my devices will be pretty simple – i’ll just publish some values from a sensor to my broker; and do the heavy lifting of analysing and acting on the readings using a “real” computer or server. The devices will be simple and low-powered so a lightweight protocol like MQTT seems like a good choice.

It looks like the premier open source broker for MQTT is Mosquitto; so let’s use that to get a broker up and running; publish some messages to it; and have a subscriber log those messages out to the console. This, by the way; is all going to be on Debian Jessie.

I don’t like to “pollute” my laptop with every hobby project that momentarily grabs my attention; so first let’s get docker installed and then start up the toke/mosquitto container.

sudo apt-get install docker.io
sudo docker run -ti -p 1883:1883 -p 9001:9001 toke/mosquitto

Next we’ll run up a couple of python scripts in a virtualenv: (I assume you’ve already done a apt-get virtualenv to install virtualenv and Python on your system) These will, respectively; publish messages to the broker (under a test topic) and subscribe to that topic.

mkdir mqtt-test
cd mqtt-test
virtualenv env
source env/bin/activate
pip install paho-mqtt

publisher.py

#!/usr/bin/env python
import time
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

client = mqtt.Client()
client.on_connect = on_connect
print("I'm alive!")
client.connect("localhost", 1883, 60)

while True:
    client.publish("test", "This is a test transmission!")
    time.sleep(1)

subscriber.py

#!/usr/bin/env python
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))
    client.subscribe("test")

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
print("I'm alive!")
client.connect("localhost", 1883, 60)

client.loop_forever()

Don’t forget to chmod +x *.py and then you can ./publisher.py and ./subscriber.py in two separate consoles to see your dockerised MQTT broker in action. Now I just need to wait for my devices to be delivered and I can get to the interesting bit!