FreeBSD / Desktop Environment /

Xfce4 WiFI Link Status Notifications with xfce4-notifyd and devd

In terms of suitability as a mobile (laptop) OS, FreeBSD 9.1 offers some major improvements for wireless networking and solid support for Intel KMS / SandyBridge GMA HD video. I began tracking and building development branches on an Asus k53e i5 laptop about 14 months ago and was pleased to see that every piece of hardware for this machine is supported out-of-the-box in 9.1-RELEASE, even down to the integrated web cam using FreeBSD's multimedia/webcamd. Performing a network based install over WiFI (AR9285) with bsdinstall is as easy as it was on a wired connection using the old sysinstall.

I spent a few years developing on a FreeBSD workstation with Xfce so it was the natural choice for the laptop. Again, in terms of a solid desktop OS experience, Xfce on FreeBSD delivers. It just kind of odd when you lose association with an access point and the Xfce panel plugins for network activity don't offer any sort of reliable indicators (or they're covered by full-screen terminals). In comes the toast.

Configuration

Dependencies

Add directives to /etc/devd.conf

Here we simply create (or modify existing entries) to catch LINK_UP/DOWN notifications for 802.11 devices. You should replace USERNAME with the user you run your desktop environment under. Also be sure that you only have one entry for the 802.11 media-type for LINK_UP and LINK_DOWN as to not create duplicate entries. su is used to issue the command as your user so that notifyd knows which display to output to, otherwise it ends up looking for an X display for the root user.

# wifi notification directives
notify 0 {
  match "system"  "IFNET";
  match "type"    "LINK_UP";
  media-type      "802.11";
  action "/etc/rc.d/dhclient quietstart $subsystem";
  action "su USERNAME -c 'xfcetoast $type $subsystem'";
};

notify 0 {
  match "system"  "IFNET";
  match "type"    "LINK_DOWN";
  media-type      "802.11";
  action "su USERNAME -c 'xfcetoast $type $subsystem'";
};

The scripts

Create executable xfceinit script in /usr/local/bin

Because of the way that devd functions, we must restart it from our user environment only after the X server is created in order for the relay to notifyd to reach the proper display. It is worth noting that the sudo command issued below obviously requires sudo access without a password-- This is intended as an implementation on a personal laptop workstation and if you are using it in any other situation I recommend you limit the ability to sudo without a password to a specific command (the devd rc.d script in this instance) or find a workaround (I tried, trust me).

#!/bin/sh
# identify ap and reinitialize devd
xfcetoast BOOT
sudo /etc/rc.d/devd restart

Create executable xfcetoast script in /usr/local/bin

Note the highlighted apcache variable below-- you should choose a suitable location for this small temporary file (like your users home directory). Be sure to use the full path (~/ will not work) as this command is piped through su -c from the devd directives.

#!/bin/sh

state=$1
interface=$2
apcache='/usr/home/user/.wifiap'

if [ "$state" == "BOOT" ]; then
  ap=`ifconfig | grep -o 'ssid.*channel...' | awk '{print $2}'`
  echo $ap > $apcache
elif [ "$state" == "LINK_UP" ]; then
  ap=`ifconfig | grep -o 'ssid.*channel...' | awk '{print $2}'`
  echo $ap > $apcache
  message=`echo -e "($interface) Link state changed to UP \nConnected to wireless network: '$ap'"`;
  notify-send "Network Status" "$message" --icon=dialog-information
else
  ap=`cat "$apcache"`
  message=`echo -e "Lost connection to wireless network: '$ap' \n($interface) Link state changed to DOWN"`;
  notify-send "Network Status" "$message" --icon=dialog-error
fi

Complete the setup and execute

Enable xfceinit in Xfce's Session and Startup