Raspberry PI configuring Wi-Fi command-line

This was a saga… i bought myself a second hand USB dongle, a Dynamode WL-700N-XS ultra compact (nano) 802.11b/g/n compatible Wi-Fi adapter, based in tbe Realtek 8188CU chipset. A fully updated USB Wi-Fi adapters list is mantained here.

Dynamode Wireless USB Nano 150mbps WL-700N-XSThis chipset is pretty plug an play on the PI with the latest Raspbian Wheezy, reported to work directly with a decent power source, no driver compilation or obscure installation, just supported out of the box by the Linux kernel. Just perfect.

I confidently connect the dongle in the PI, the USB device was properly recognized:

# lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 0bda:8176 Realtek Semiconductor Corp. RTL8188CUS 802.11n WLAN Adapter

also on dmesg

# dmesg
[    3.171681] usb 1-1.2: new high-speed USB device number 4 using dwc_otg
[    3.293726] usb 1-1.2: New USB device found, idVendor=0bda, idProduct=8176
[    3.302266] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    3.311142] usb 1-1.2: Product: 802.11n WLAN Adapter
[    3.317650] usb 1-1.2: Manufacturer: Realtek
[    3.323401] usb 1-1.2: SerialNumber: 00e04c000001
...
[   15.830604] usbcore: registered new interface driver rtl8192cu

and ifconfig, reports a wlan0, so by now everything looked great. I followed an tutorial about configuring wireless on PI, and no connection, then another, and no connection… shit!!! Then of course i dump the PI tutorials (you can guess the technical level as low when you find “reboot to load the new values”….). Moved to good old Linux documentation, as Raspbian is just another Debian clone.

So before messing with /etc/network/interfaces and /etc/wpa_supplicant/wpa_supplicant.conf the best debug tool is the command ‘iwlist wlan0 scan‘, that should print the available wireless networks. And with this dongle i was getting none (even at 10 centimeters of the wireless router). Long story short, after testing the dongle in other computers (and even other OS – yes, i washed my hands already) i found out the dongle is simply damaged and working rather randomly.

After replacing the dongle (thanks Delaman) by another of the exact same model, things started to work properly, iwlist wlan0 scan started to work right and i could see my wireless network, and the neighbors networks also.

From this point i could confidently resume the wireless network setup. First thing the /etc/network/interfaces:

auto lo
iface lo inet loopback

iface eth0 inet dhcp

auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp

the important lines here are those 3 referring to the wlan interface and should be added to the configuration file.

Then the /etc/wpa_supplicant/wpa_supplicant.conf that holds the network security configuration. First i tried some of the suggested configurations in the Internets, but i was just getting the error: “failed to parse ssid ‘MY_NETWORK_NAME’” and the likes. So, go with the wpa_passphrase command to generate a network block configuration:

wpa_passphrase YOUR_NETWORK_NAME password

Now copy and replace the generated network block to /etc/wpa_supplicant/wpa_supplicant.conf, it should look something like this (a quite simple and clean configuration):

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
        ssid="NETWORK_NAME"
        #psk="password"
        psk=generated_by_wpa_passphrase
}

You can heep the first two lines, as they provide an interface to the wpa_supplicant via the wpa_cli command.

Don’t have to reboot, i tested this while ethernet connected. Restart the wlan0 interface and reload the configuration into the supplicant thing:

ifdown wlan0
ifup wlan0
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf

And there, ifconfig shows an active Wi-Fi connection on wlan0. From other computer, the wlan0 IP responds on pings and is possible to SSH. Now disable the ethernet connection:

ifdown eth0

disconnect the ethernet cable, and there your PI is free to move around without the network cable.

Raspberry PI follow-up

raspberry_pi_logoSo, i did get a (actually 2) Raspberry PI and did get it up and running, it was time to do anything useful with it…

Time to setup a Samba server for network recording of security camera feeds. I went along with SWAT, a web based graphical interface to samba configuration. Like all Debian based software, the installation process is pretty straight forward,

apt-get update
apt-get install swat

And auto-magically it installs everything that you need, it evens adds the needed configuration line to /etc/inetd.conf 🙂

[global]
        netbios name = INTRANET
        server string = %h server
        map to guest = Bad Password
        syslog = 0
        log file = /var/log/samba/log.%m
        max log size = 1000
        dns proxy = No
        guest account = nobody
        usershare allow guests = Yes
        panic action = /usr/share/samba/panic-action %d
        idmap config * : backend = tdb

[public1]
        comment = Samba Public 1
        browsable = yes
        public = yes
        writable = yes
        read only = No
        guest ok = Yes
        path = /media/usb0/samba/cam1/

[public2]
        comment = Samba Public 2
        browsable = yes
        public = yes
        writable = yes
        read only = No
        guest ok = Yes

Then just point your browser to the PI ip at port 901. Curious enough, i found the SWAT tool too complex for the simple configuration that i wanted: i trust all users in the network, so my need was just two shares that anyone could read/write. So, i ditch SWAT and went on to good ol’style configuration file editing. The final /etc/samba/smb.conf that is working for me:

Fired up samba
# service samba restart

And the cams had no problem finding the samba shares and recording into them.

Next step was to get an easy way to navigate and download recordings. Of course you can also use the samba shares to navigate and read, but specially to outside access it would implied to configure a VPN access to the network (you don’t want your security camera feeds exposed in the Internets with read/write permissions to the world, right?). I went for HTTP with some kind of a file explorer software that allows users/permissions, file/directory browsing, and file download. For the server part i opted for lighttpd, a small footprint server, and for the voodoo PHP (all pretty familiar technology to me). Again the installation is for dummies:

apt-get install lighttpd
apt-get install php5-cgi

Then just a tiny adjustment at /etc/lighttpd/lighttpd.conf:

index-file.names            = ( "index.php", "index.html", "index.lighttpd.html" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

fastcgi.server = ( ".php" => ((
                     "bin-path" => "/usr/bin/php-cgi",
                     "socket" => "/tmp/php.socket"
                 )))

and restart it. For the software i went for the super nice, cool and powerful AjaXplorer. Just download it and untar to /var/www directory. Then point your browser to PI and log in with admin/admin (changed the password) and then it was just a matter of setting up a user account and a repository pointing to /media/usb0/samba/ (the parent directory of both samba shares).

Now, only one thing left, clean up and report. What to use? Of course PHP again. But this one in command line, so i installed the CLI version.

apt-get install php5-cli

And i did i script that cleans up old recordings and send me a daily report email using basic functions and the great PHPMailer class.

require('phpmailer/class.phpmailer.php');

function deleteDir($dir, $days) {
    $now      = time();
    $diff     = 60*60*24*$days;
    $treshold = $now - $diff;

    $d = dir($dir);
    while (false !== ($entry = $d->read())) {
        if ($entry != '.' && $entry != '..') {
            $year  = substr($entry, 0, 4);
            $month = substr($entry, 4, 2);
            $day   = substr($entry, 6, 2);

            if (mktime(0, 0, 0, $month, $day, $year) < $treshold)
                exec("/bin/rm -rf ".$dir.$entry);
        }
    }

    $d->close();
}

function getDirUsage($dir) {
    exec("/usr/bin/du -sh ".$dir, $output, $return);

    if ($return > 0)
        return 0;

    $output = $output[0];
    $output = explode("\t", $output);

    return $output[0];
}

/*
 * DELETE OLD FILES, +30d
 */

deleteDir('/media/usb0/samba/cam1/video/', 30);
deleteDir('/media/usb0/samba/cam2/video/', 30);

/*
 * GET USED/FREE SPACE
 */

exec ('df -h', $output);
foreach ($output as $line) {
    if (strpos($line, '/media/usb0')) {
        $disk_line = $line;
        break;
    }
}

$disk_line = explode(" ", $disk_line);
$disk_line = array_values(array_filter($disk_line));

$disk_used_space = $disk_line[2];
$disk_used_perc  = $disk_line[4];
$disk_free_space = $disk_line[3];

/*
 *  GET YESTERDAY RECORDINGS USAGE
 */

$yesterday  = date("Ymd", time() - 60 * 60 * 24);
$cam1_space = getDirUsage('/media/usb0/samba/cam1/video/'.$yesterday.'/');
$cam2_space = getDirUsage('/media/usb0/samba/cam2/video/'.$yesterday.'/');

/*
 *  GET YESTERDAY RECORDINGS USAGE
 */

$yesterday  = date("Ymd", time() - 60 * 60 * 24);
$cam1_space = getDirUsage('/media/usb0/samba/cam1/video/'.$yesterday.'/');
$cam2_space = getDirUsage('/media/usb0/samba/cam2/video/'.$yesterday.'/');

/*
 * SEND REPORT EMAIL
 */

$mail = new PHPMailer();
$mail->IsSMTP();                            // telling the class to use SMTP
$mail->SMTPAuth = true;                     // enable SMTP authentication
$mail->Port     = 25;                       // set the SMTP port
$mail->Host     = "mail.domain.com";        // SMTP server
$mail->Username = "username";               // SMTP account username
$mail->Password = "password";               // SMTP account password

$mail->From     = "email@domain.com";
$mail->FromName = "Descriptive email";
$mail->AddAddress("my_email@domain.com");

$mail->CharSet = "UTF-8";
$mail->Subject  = "Cam Report";
$mail->Body     = "YESTERDAY RECORDINGS\n".
                  "Cam 1: $cam1_space\n".
                  "Cam 2: $cam2_space\n".
                  "\n\n".
                  "HDD SPACE STATUS\n".
                  "Free: $disk_free_space\n".
                  "Used: $disk_used_space ($disk_used_perc)\n";
$mail->WordWrap = 50;

if(!$mail->Send())
        error_log($mail->ErrorInfo);

Then just run it daily with cron
30 3 * * * /usr/bin/php /path/to/script/cams.php > /dev/null

For now that’s all, but i guess there will be more updates on the Raspberry PI as i have still some ideas floating in my head.

Raspberry PI first steps

As every and each true geek, i get myself a Raspberry PI. First error, i ordered only the Raspberry, should have bought also a case (i will buy one soon, but with added shipment costs…).

First choice to make, a cheap decent SD card. I bought a 4GB SD card, 6 class (meaning 6 MB/sec – higher the better). The OS image (Raspbian – yet another debian clone) has a considerable size, almost 2GB, so anything smaller than 4GB is probably not a very good idea…

DSC00437Powered it up, and first problem, even though i had an HDMI connection to my TV screen no output was detected – shit! Besides no output, everything seemed normal and in my router it was registered a new device, so ssh to the assigned IP and could log easy with the default pi/raspberry credentials…. (yes i did tried with another cable and still no output), strangely enough if connected to a monitor with the same HDMI cable works fine and also the TV reads perfectly from other HDMI inputs (Laptop, PS3)….

Still about this, i have found that you can do a lot of tweaking in Raspberry HDMI settings, i will thinker with the various options and then report back:
http://elinux.org/RPi_config.txt#Video_mode_options

After boot you must (or at least should) re-size (or make another) partition to reclaim the entire card space. After that i wanted to connect an external HDD, as documented and expected, if connected directly to one of the Raspberry USB ports there is not enough power and the Raspberry crashes and reboots (so does the HDD).  So, i went out to get a self powered cheap USB hub…

DSC00435I connected the USB Hub, and plugged in the Raspberry to it, worked fine. And then the HDD, also powered up nice and no more crashes and reboots as expected. But the damn thing wasn’t recognized… why? Yet another rookie mistake… the micro USB input on the Raspberry is power input only, doesn’t support data, so i fixed it with another external power adapter providing power to the Pi. I think another cable running from the USB hub would also do the job.

Of course i did setup root ssh access (as all good security practices advise not to do, but what the heck i like to live on the edge). Boot, and minimum setup complete, time to move to the real fun stuff 🙂

Update:
Raspberry PI with Raspbian “Wheezy” connected to a LG 50PV350 trough HDMI. The TV set reports “no signal” and shows no image. To fix this, open the SD card boot partition edit config.txt and add

hdmi_force_hotplug=1
hdmi_group=1
hdmi_mode=16

this will set the PI output to HDMI always even if no device is detected, group 1 means TV (2 is monitor) and mode is set to 1080p.