Linux - networking without a UI using nmcli

The XMonad setup I described in this blog post should be functional and extendable enough to get started. However there is one glaring omission - no easy way to configure any wifi or 3G/4G networks you want to connect to. So it's useful to know a little about nmcli, the command-line interface to NetworkManager. This can also be useful if you're futzing around with a linux box remotely.

Fire up an xterm and run the following to check out which network interfaces you have available, and what state they are in:

    $ nmcli dev status
    DEVICE             TYPE      STATE            CONNECTION  
    cdc-wdm0           gsm       disconnected     -- 
    wlan0              wifi      disconnected     --
    F4:31:C3:30:E3:6F  bt        disconnected     --          
    eth0               ethernet  unavailable      --          
    lo                 loopback  unmanaged        --          

So we've five interfaces, none of which are connected to anything. I'll focus on the extremely common use-cases - connecting to open and secured wifi networks using the "wlan0" device, as well as connecting to 3G/4G networks using the "cdc/wdm0" device.

WiFi

To view available networks near you:

    $ nmcli dev wifi list
    *  SSID       MODE   CHAN  RATE       SIGNAL  BARS  SECURITY         
       Rotor bar  Infra  8     54 Mbit/s  72      ▂▄▆_                   
       ahnet      Infra  11    54 Mbit/s  42      ▂▄__  WEP              
       eduroam    Infra  1     54 Mbit/s  15      ▂___  WPA1 WPA2 802.1X 
       vakan      Infra  13    54 Mbit/s  12      ▂___  WEP              
       JAMU       Infra  1     54 Mbit/s  10      ▂___                   

If we want to connect to "Rotor bar" - an open, unsecured network, we can do the following

    $ nmcli device wifi connect "Rotor bar"
    Device 'wlan0' successfully activated with 'ccb0a5a1-ef8d-4fea-966f-7999f2611345'.

If this network was instead secured with the password "123456789" we would instead have used:

    $ nmcli dev wifi con "Rotor bar" password "123456789"

And when we want to disconnect from the WiFi, we can run:

    $ nmcli dev disconnect iface wlan0

And if we wanted to reconnect to this network:

    $ nmcli con up id "Rotor bar"

Mobile Broadband

We can check if you have already set up a Mobile Broadband (3G, LTE, etc seem to be appear as type "gsm") connection :
    $ nmcli connection show | grep gsm
    Vodafone CZ             2756323d-e364-49dc-9d86-92b8c2a44d15  gsm              --     

In my case I'd previously setup "Vodafone CZ" using the NetworkManager applet in XFCE, however if we want to do this in the CLI all we need to do is make sure a config file is present in the /etc/NetworkManager/system-connections folder which has the right setup

    $ sudo cat /etc/NetworkManager/system-connections/Vodafone\ CZ
    [connection]
    id=Vodafone CZ
    uuid=2756323d-e364-49dc-9d86-92b8c2a44d15
    type=gsm
    autoconnect=false
    permissions=
    secondaries=

    [gsm]
    apn=internet
    number=*99***1#
    password-flags=1
    pin=1234

    [serial]
    baud=115200

    [ipv4]
    dns=8.8.8.8;
    dns-search=
    method=auto
 
    [ipv6]
    addr-gen-mode=stable-privacy
    dns-search=
    ip6-privacy=0
    method=auto

So, assuming you're using Vodafone in the Czech Republic you can use this config, tweak the PIN as necessary (it's the SIM PIN, btw) rerun nmcli connection show to check NetworkManager knows about it, and then run the following to bring it up:

    $ nmcli connection up id "Vodafone CZ"
    Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/27)
And to disconnect
    $ nmcli connection down id "Vodafone CZ"
    Connection 'Vodafone CZ' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/27)

So there we have it - it's possible there's a strange configuration that you need, so you may have to dig into the nmcli man pages - but as long as you have some sort of internet connection I found the followingpages useful:

BeagleBone Black - iPhone as keyboard/mouse

Note: I wrote this a while ago specifically for my BeagleBone Black so some of the instructions refer to "opkg" - the package manager used by Ångström Linux. It looks like they've moved on to use Debian instead of Angstrom nowadays, but realistically you can adapt this guide and use the software on any linux distro on any device.

I thought it would be an interesting exercise to use my iPhone as an input device instead of a physical mouse and keyboard. It turns out it's pretty simple, thanks to Tuomas Räsänen's cool python-uinput module together with pybonjour for simple device discovery via Bonjour.

The "server" running on the Beagle and the iOS "client" (bad metaphors, sorry) can be retrieved via git:

$ git clone https://github.com/smcl/iBeagle
$ cd iBeagle

Preparing your Beaglebone Black

First copy the file iBeagle.py file to your beagle.

$ cd iBeagleServer
$ scp iBeagle.py beaglebone.local: # or whatever the username/IP is

Next there's a little bit of setup on the BeagleBone Black is required, as a kernel module and a couple of libraries are required

$ ssh beaglebone.local

Load the "uinput" module. this requires libudev

$ sudo modprobe uinput

The python module for uinput we're using requires udev-systemd, so install via opkg

$ sudo opkg install udev-systemd
$ git clone https://github.com/tuomasjjrasanen/python-uinput.git
$ cd python-uinput && sudo python setup.py install

Ensure avahi-daemon process is up and running

$ ps ax | grep avahi | grep running

Finally setup pybonjour - bonjour library I used for this. If you're having trouble relating to libdns_sd.so see the section "Appendix - udev trouble" at the end.

$ pushd /usr/src
$ wget https://pybonjour.googlecode.com/files/pybonjour-1.1.1.tar.gz
$ pushd pybonjour-1.1.1
$ tar -xzf  pybonjour-1.1.1.tar.gz
$ cd pybonjour-1.1.1
$ python setup.py install

Finally return to your iBeagleServer directory and run the client

$ popd && popd
$ python iBeagle.py

Preparing the iPhone Client

Currently you need to load the application using Xcode, so you'll need an iOS dev account and an iOS device authorised to your account. Open up iBeagleClient/iBeagleClient.xcodeproj, and build + run on your hardware.

When the server is running you should see your BeagleBone Black listed on the table when you launch the app. If not then try restarting the server, or waiting a few seconds.

Appendix - libudev trouble

I actually had a bit of trouble with this step initially. libdns_sd.so was missing, so I retrieved the avahi sources and built my own copy. The libdns_sd.so library was missing on my version of Angstrom Linux, so I built and installed it separately (which is slightly hacky, there's probably a more sensible way to achieve this)

$ wget http://avahi.org/download/avahi-0.6.31.tar.gz
$ tar -xzf avahi-0.6.31.tar.gz && cd avahi-0.6.31

We need to grab some pre-requisites + set PTHREAD_CFLAGS

$ export PTHREAD_CFLAGS='-lpthread'
$ sudo opkg install libssp-dev
$ sudo opkg install libintltool

And run configure so we only build as little as possible to just get the library we want

$ ./configure --disable-static --disable-mono --disable-monodoc --disable-gtk3 --disable-gtk --disable-qt3 --disable-python --disable-qt4 --disable-core-docs --enable-compat-libdns_sd --disable-tests --with-distro=none
$ make

Then (without running make install) we copy libdns_sd.so and libdns_sd.h into /usr/lib and /usr/include respectively

$ cp ./avahi-compat-libdns_sd/.libs/libdns_sd.so /usr/lib
$ cp ./avahi-compat-libdns_sd/dns_sd.h /usr/include

In my case it was trying to use libdns_sd.so.1 - so I also created a symlink to libdns_sd.so.1.