Tip for XMPP users: adjust your priority!

To declare which of my connections to my XMPP server has the ‘most important’ and ‘most chattable’ status, I use XMPP’s <priority /> mechanism.

Basics of XMPP connections

XMPP connection is actually two streams of XML, one going from the client to the server, and the other from the server to the client. (If your client exposes a feature typically called “XML Console”, use it to see the traffic.) Each XMPP connection has a “resource” string attached to it (and generally requested by the client — though the server can opt to override it). Typically, clients will set it to a random string, to the client name, or to the hostname. Together with your account name (“Jabber ID”), resource forms a globally-unique way to reach you in the XMPP network; for example: username@example.net/GajimAtWork.

Basics of XMPP presences

Each XMPP connection’s status text and status type are declared using a <presence /> tag. Just an empty <presence /> tag means “My status type is ‘online’, with no status text and with priority set to zero”. To specify each of these, according to RFC3921’s section 2.2.2, you add extra tags inside the <presence />1:

  <status>This is my status</status>

The <presence /> will be broadcast to users subscribed to them, whom you authorized to receive them.

How priority is used

The <priority /> of a <presence /> is used by clients for a variety of things, including prioritizing which status to display to users. And, even more importantly, servers use <priority /> to determine where to deliver <message />s that are directed towards a bare JID, and not towards a full JID. (A bare JID does not include the resource string, and thus describes an account; a full JID includes a resource string, and thus described a connection.)

Servers will deliver <message />s aimed at a bare JID to all connections that have the top priority. For example, if you have the following connections:

Resource Status Priority
GajimAtWork online 15
PidginAtWork online 15
OldPhone online 14
NewPhone online 14
GajimAtHome away 2
Tablet away 1
Webmail online 1

you will receive the message to GajimAtWork and PidginAtWork. (Specifics of this may be overridden by the server, especially if some XEP2 such as ‘carbon copies’ is in use.) See more information in RFC3921, section 11.1 which discusses how the server should handle incoming stanzas (incl. those directed at bare JID).

And let’s say you absolutely don’t want to be disturbed to a certain device, unless this device is directly contacted (by specifying full JID). In that case, specifying a negative priority (say, -1) is handy, which tells the server not to deliver the message at all, even if it’s the top priority. You can still initiate outgoing chats; receiving a message commonly makes the client switch to sending to a bare JID from which it was received.

How priority is useful

Many of the better clients let you associate a priority with a status type; that is, if you set your status type (<show />) to dnd3, you can declare that your <priority /> should also change to 20; and if you set your status type to online (that is, <show /> is missing), your <priority /> should change to 40.

Combined with the fact that, all things equal, I would prefer to answer to incoming chats on my desktop, I began using the following setup in clients that support the aforementioned functionality:

show Usual name in UI Device type Priority
chat Free for chat desktop 50
none Available desktop 30
dnd Busy desktop 25
away Away desktop 10
xa Extended Away desktop 2

For mobile, just decrease by one:

show Usual name in UI Device type Priority
chat Free for chat mobile 49
none Available mobile 29
dnd Busy mobile 24
away Away mobile 9
xa Extended Away mobile 1

What happens if your client does not support <priority/ >?

Useful clients which don’t support setting <priority /> — for example, Conversations for Android (source) — will have priority set to zero. Such a client, however, will be useful mainly because it supports and uses replacement XEPs such as XEP-0280: Message Carbons, which will ensure the message is still delivered to that device. There will be dark sorcery involving XEP-0333: Chat Markers which will help to reduce the number of devices that are making noises, similar to experience in Hangouts.

Some say statuses and priority are not useful

Some say statuses and priority are not useful. I respect this opinion, but my personal experience with Hangouts where exactly this is the norm tells me otherwise. I’d rather automate declaring my status than have it disappear from my contacts’ feeds. “Locked my workstation? It’s 12:00-14:00? Probably at lunch.” and similar personalized heuristics. “I’ve been toying with my phone for more than 5 min? I am probably free for chat — but do tell the contacts that I am on my phone.”

That said, I do like and appreciate much of the modern experiences certain statusless client(s) have. There is something to be said for simply receiving messages where they should arrive and notify based on actual activity. I like the simplicity of it.

Then again, if I am at work, I probably don’t want to chat with you; how will non-personalized client know that I’m busy out of the box? Or even more importantly, how will it relay that to my contacts? Can I more simply teach my phone to shut up based on my personal daily routine?

shrug I think I can. Your mileage may vary.

  1. <presence />s are used for more than this even in base RFCs. They can be directed towards one
    specific JID, instead of server just broadcasting them. This can in turn be used as a mechanism
    to declare that you would like to subscribe to a particular user’s presences. But, this is a
    discussion on <priority /> tag, so refer to the RFC for more information. 

  2. XEP: XMPP Extension Protocol. 
  3. dnd maps to ‘busy` in UI. 

“Website Obesity Crisis”

Interesting talk by Maciej Cegłowski: Website Obesity Crisis.

What do I mean by a website obesity crisis?

Here’s an article on GigaOm from 2012 titled “The Growing Epidemic of Page Bloat”. It warns that the average web page is over a megabyte in size.

The article itself is 1.8 megabytes long.

Here’s an almost identical article from the same website two years later, called “The Overweight Web”. This article warns that average page size is approaching 2 megabytes.

That article is 3 megabytes long.

If present trends continue, there is the real chance that articles warning about page bloat could exceed 5 megabytes in size by 2020.

The problem with picking any particular size as a threshold is that it encourages us to define deviancy down. Today’s egregiously bloated site becomes tomorrow’s typical page, and next year’s elegantly slim design.

I would like to anchor the discussion in something more timeless.

To repeat a suggestion I made on Twitter, I contend that text-based websites should not exceed in size the major works of Russian literature.

This is a generous yardstick. I could have picked French literature, full of slim little books, but I intentionally went with Russian novels and their reputation for ponderousness.

In Goncharov’s Oblomov, for example, the title character spends the first hundred pages just getting out of bed.

This seems good to keep in mind. It’s important, given recent developments such as Accelerated Mobile Pages project. How much cruft should there be on a page? When’s the last time you measured the loading size+time of your page? When’s the last time you did something useful about it?

Maybe this site is something to look at and think about?

A PulseAudio primer, and setting up an equalizer

Once again, some notes for my own personal reference, which may help others as well. And if something is wrong, let me know.

Written only from the user’s perspective.

What is it?

Quoting from the description:

PulseAudio is a sound system for POSIX OSes, meaning that it is a proxy for your sound applications. It allows you to do advanced operations on your sound data as it passes between your application and your hardware. Things like transferring the audio to a different machine, changing the sample format or channel count and mixing several sounds into one are easily achieved using a sound server.

PulseAudio is designed for Linux systems. It has also been ported to and tested on Solaris, FreeBSD, NetBSD, MacOS X, Windows 2000 and Windows XP.

PulseAudio is an integral part of all relevant modern Linux distributions and used in various mobile devices by multiple vendors.

It’s running as a daemon. My understanding is that it runs in userspace.

Main concepts

PulseAudio is an audio graph. It uses a variety of modules to expose sinks and sources. Sinks and sources seem to be what Apple’s Core Audio, another audio graphing system, would all be “audio units”, where there could be some inputs, and some outputs. Here, sinks seem to be intended as playback devices, and input devices such as microphones are sources.

Clients can create sink inputs.

Main tools

As a user, main CLI tools used to interact will be pactl and pacmd. I’m fine with pactl, but pacmd seems to expose more options.

To view all objects known to PulseAudio, use pactl list.

Module #0
        Name: module-device-restore
        Usage counter: n/a
                module.author = "Lennart Poettering"
                module.description = "Automatically restore the volume/mute state of devices"
                module.version = "4.0"

Module #1
        Name: module-stream-restore
        Usage counter: n/a
                module.author = "Lennart Poettering"
                module.description = "Automatically restore the volume/mute/device state of streams"
                module.version = "4.0"


Module #21
        Name: module-filter-apply
        Usage counter: n/a
                module.author = "Colin Guthrie"
                module.description = "Load filter sinks automatically when needed"
                module.version = "4.0"

Sink #0
        State: SUSPENDED
        Name: alsa_output.pci-0000_05_00.1.hdmi-stereo
        Description: GF108 High Definition Audio Controller Digital Stereo (HDMI)
        Driver: module-alsa-card.c
        Sample Specification: s16le 2ch 44100Hz
        Channel Map: front-left,front-right
        Owner Module: 5
        Mute: no
        Volume: 0:  84% 1:  84%
                0: -4.39 dB 1: -4.39 dB
                balance 0.00
        Base Volume: 100%
                     0.00 dB
        Monitor Source: alsa_output.pci-0000_05_00.1.hdmi-stereo.monitor
        Latency: 0 usec, configured 0 usec
                alsa.resolution_bits = "16"
                device.api = "alsa"
                device.vendor.id = "10de"
                device.vendor.name = "NVIDIA Corporation"
                device.product.id = "0bea"
                device.product.name = "GF108 High Definition Audio Controller"
                device.string = "hdmi:2"
                device.buffering.buffer_size = "65536"
                device.buffering.fragment_size = "32768"
                device.access_mode = "mmap+timer"
                device.profile.name = "hdmi-stereo"
                device.profile.description = "Digital Stereo (HDMI)"
                device.description = "GF108 High Definition Audio Controller Digital Stereo (HDMI)"
                alsa.mixer_name = "Nvidia GPU 14 HDMI/DP"
                alsa.components = "HDA:10de0014,10de0101,00100100"
                module-udev-detect.discovered = "1"
                device.icon_name = "audio-card-pci"
                hdmi-output-0: HDMI / DisplayPort (priority: 5900, not available)
        Active Port: hdmi-output-0

Sink #1
        State: SUSPENDED
        Name: alsa_output.pci-0000_00_1b.0.analog-stereo
        Description: Built-in Audio Analog Stereo
Source #2
        State: SUSPENDED
        Name: alsa_input.pci-0000_00_1b.0.analog-stereo
        Description: Built-in Audio Analog Stereo
        Driver: module-alsa-card.c
        Sample Specification: s16le 2ch 44100Hz
        Channel Map: front-left,front-right

Client #5
        Driver: protocol-native.c
        Owner Module: 11
                application.name = "GNOME Volume Control Media Keys"
                native-protocol.peer = "UNIX socket client"
                native-protocol.version = "28"
                application.id = "org.gnome.VolumeControl"
                application.icon_name = "multimedia-volume-control"
                application.version = "1.0"
                application.process.id = "30127"
                application.process.user = "ivucica"
                application.process.host = "MYHOSTNAME"
                application.process.binary = "unity-settings-daemon"
                application.language = "en_US.UTF-8"
                window.x11.display = ":0"
                application.process.machine_id = "MYMACHINEID"
                application.process.session_id = "c14"

Card #1
        Name: alsa_card.pci-0000_00_1b.0
        Driver: module-alsa-card.c
        Owner Module: 6
                alsa.card = "0"
                alsa.card_name = "HDA Intel PCH"
                alsa.long_card_name = "HDA Intel PCH at 0xef340000 irq 86"
                alsa.driver_name = "snd_hda_intel"

Sink Input #0
        Driver: protocol-native.c
        Owner Module: 11
        Client: 7
        Sink: 1
        Sample Specification: s16le 2ch 44100Hz
        Channel Map: front-left,front-right
        Format: pcm, format.sample_format = "\"s16le\""  format.rate = "44100"  format.channels = "2"  format.channel_map = "\"front-left,front-right\""
        Corked: no
        Mute: no
        Volume: 0: 100% 1: 100%
                0: 0.00 dB 1: 0.00 dB
                balance 0.00
        Buffer Latency: 60408 usec
        Sink Latency: 21966 usec
        Resample method: n/a
                application.icon_name = "google-chrome"
                media.name = "Playback"
                application.name = "Chrome"
                native-protocol.peer = "UNIX socket client"
                native-protocol.version = "28"
                application.process.id = "13436"
                application.process.user = "ivucica"
                application.process.host = "MYHOSTNAME"
                application.process.binary = "chrome (deleted)"
                application.language = "en_US.UTF-8"
                window.x11.display = ":0"
                application.process.machine_id = "MYMACHINEID"
                application.process.session_id = "c14"
                module-stream-restore.id = "sink-input-by-application-name:Chrome"

Using pactl list short, the output will be more ambiguous. Let’s filter it to show only sink-inputs using pactl list short sink-inputs.

0   1   7   protocol-native.c   s16le 2ch 44100Hz

Changing default output

When an app starts playing an audio stream, it gets sent to the default sink. Let’s change it to go from the current output to ‘hdmi-stereo’.

$ pactl list short sinks
0   alsa_output.pci-0000_05_00.1.hdmi-stereo    module-alsa-card.c  s16le 2ch 44100Hz   SUSPENDED
1   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   RUNNING
$ pactl set-default-sink 0

Moving existing sink inputs to another sink

If an application is already playing audio, it will not switch over to the new sink.

$ pactl list short sink-inputs
0   1   7   protocol-native.c   s16le 2ch 44100Hz
// move sink input 0 to sink 1:
$ pactl move-sink-input 0 1
// alternatively:
$ pactl move-sink-input 0 alsa_output.pci-0000_00_1b.0.analog-stereo

GUI for the above operations

One of the more lightweight GUI solutions seems to be pavucontrol.

Setting up equalizer

The modules may not be loaded. (Optionally verify with pactl list modules.)

$ pactl load module-equalizer-sink
$ pactl load module-dbus-protocol

This creates a new sink.

Upstream documentation claims the equalizer should already set itself as the default. Existing sink inputs definitely didn’t move over to the new sink. I’m using Ubuntu 14.04; YMMV.

None of the arguments mentioned by upstream docs (sink_name=equalized master=alsa_output.pci-0000_00_1b.0.analog-surround-51 set_default=true) worked for me. I would suspect they are simply post-trusty additions.

Instead, here’s my manual steps. (This could be more automated simply by using variables. Still, given that these are semi-educational notes, I’m opting for showing how to interpret outputs.)

// Find the ID of the first equalizer sink.
// If you suspect you may have more, skip everything after 'grep equalizer' and manually handle.
$ pactl list short sinks | grep equalizer | head -n1 | awk '{print $1;}'
$ pactl set-default-sink 4
$ pactl list short sink-input | awk '{print $1;}'
$ pactl move-sink-input 2 4
$ pactl move-sink-input 6 4
$ pactl move-sink-input 7 4

Adjusting equalizer settings using qpaeq

Qt PulseAudio Equalizer or qpaeq is available from PulseAudio source tree. For example, take it from a mirror on GitHub, make it executable and run it. (Before running it, of course, read through this code you’re grabbing from a random website on the Internet.)

$ wget https://raw.githubusercontent.com/pulseaudio/pulseaudio/master/src/utils/qpaeq
$ chmod 755 qpaeq
$ ./qpaeq

Dealing with issues

If something doesn’t go right, kill the PulseAudio daemon pulseaudio -k. Your desktop environment is probably going to restart it by itself. Otherwise, something like nohup pulseaudio & should probably help. Then, reload the modules.

Upstream docs also say you may want to disable tsched, for example in /etc/default/pulse.pa:

### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect tsched=0
### Alternatively use the static hardware detection module (for systems that
### lack udev support)
load-module module-detect tsched=0

I’m thinking, that may be also the right place for loading the equalizer and dbus module. Although, ~/.config/pulse/default.pa may be an even saner one. Not sure yet.

Good luck!

Ubiquiti’s mPower ships with ancient Dropbear 0.51 and no forced command support

Bane of all hardware products — software updates.

The exciting mPower and mPower PRO power strips that I am otherwise happy with are, even in the latest firmware version, sadly shipping with an ancient version of Dropbear. This means no command restriction in authorized_keys file.


In hopes that their firmware release engineering processes are such that swapping one Dropbear version for another will not take too much effort, I’ve opted to file a support request, upon which I was directed to post a request on the forums.

Sadly, I don’t think I could even work around this with multiuser support and putting together a .profile, given that this device is not really built for multiuser use. (That is, it seems to have one user, root, which may or may not be renamed. For example, in /etc/passwd, uid 0 on my devices is called ivucica.)

If they do, hopefully they opt for the latest release, as apparently 0.52 and later had security vulnerabilities exactly with command= restriction.