Arm9 hotplug

From NAS-Central Buffalo - The Linkstation Wiki
Jump to: navigation, search

Hotplug on ARM9 This article explains (very short) how the hot plug system on the Linkstation Pro (also Live and Terasation Pro/Live - on the ARM9 series)works and shows a simple way to alter it in order to perform custom actions upon hot plugging.

The hotplug system

When plugging in a new usb device /sbin/hotplug is called. Before the call a number of environment variables are set (see For this article the most important are:

$PRODUCT   the product ID of the device
$ACTION    "add"/"remove" depending on if the device is plugged or unplugged
$PATH      /sbin:/bin:/usr/sbin:/usr/bin

Further a parameter $1 is passed to /sbin/hotplug, that depends on the device. Depending on this parameter scripts in /etc/hotplug.d/$1/*.hotplug are called. On the linkstation pro only one script for handling external usb disks exists /etc/hotplug.d/scsi_device/usb-buffalo.hotplug.


The idea was brought to me by an article in the German IT magazine c't (16/2007). The idea in short: If you plug in a device you usually want to perform a certain action. For a camera you want to copy the images from the camera to the hard disc, if it's a mp3 player you might to put new music on it...

The mentioned article used udev and hal (hardware abstraction layer). Due to the different mechanism implemented on the arm9 stock firmware it can not be transfered directly. So we adapt the idea using the hotplug.d concept.

All we have to do is to add a user script e.g /etc/hotplug.d/usb/mydevice.hotplug and make it executable.

This is explained in the following for a Canon powershot. We download the images, rotate them according to the exif flags and store them into a date dependent folder.

Example: image downloading

When connecting the camera to the linkstation I want all images (JPG, AVI) to be copied to the hard disk into year/month folders and the photos should be rotated according to the info in the EXIF tag. During operation feedback is given by the info LED, in case of an error the diag LED starts to flash.

Copying is done using gphoto2, jhead evaluates the EXIF tag and calls libjpeg to rotate the JPG's. gphoto2 and libjpeg are available via ipkg from the optware feed, you can find a compiled jhead version (2.8) in the download section (

The script for the usb device has to be in /etc/hotplug.d/usb, its name has to have the form *.hotplug and it has to be executable. It is called from /sbin/hotplug, for my camera the variable $PRODUCT is set to "4a9/313a/2" if this is the case and $ACTION is equal to "add" then it's time for action.

Currently the line for deleting the images from the camera (gphoto2 -RD) is commented out - to avoid any trouble in case there's a bug in the script. See the comments!



# user and group that'll own the images

# write error message into ERRORLOG, let error/diag led blink
    echo $1 >> $ERRORLOG

    # play signal tones
    miconapl -a bz_melody 300 a4 g4

    # blink error LED
    miconapl -a led_set_cpu_mcon diag on
    miconapl -a led_set_on_off diag on
    miconapl -a led_set_brink diag on

# copy images from camera and delete them there,
# during operation info LED flashes
    # turn info LED on and let it blink while copying from camera
    miconapl -a led_set_on_off info
    miconapl -a led_set_brink info

    # copy photos into current dir using gphoto2
    gphoto2 -P || error "Error in gphoto2 -RP, code: $?" >> $ERRORLOG

    # if everything works, uncomment next line to delete images from the camera
    # gphoto2 -RD || error "Error in gphoto2 -RD, code: $?" >> $ERRORLOG

    # turn info LED off again and clear blink status
    miconapl -a led_set_on_off info off
    miconapl -a led_set_brink info off

# automatic processing of  photo files
    # autorotate images according to the exif-flags
    # also set modification time to exif-date/time
    # exit codes of jhead: 0=OK, 1=Modified
    /opt/bin/jhead -autorot -ft *.JPG >> $ERRORLOG

    # jhead returns "1" in case of successful modification (e.g. rotation)
    if [ "$?" -lt "0"]; then
       error "Error in jhead operation, code: $?"

# move all images into photo folders
    chown $IMGUSR:$IMGGRP *.JPG *.AVI
    chmod a+rw,a-x *.JPG *.AVI

    for photo in *.JPG *.AVI; do
      if [ ! -f "$photo" ]; then
        # continue with next loop if it's not a file

      # get the year and month of the photo - separate vars if further processing is desired
      date_year=`date -r "$photo" +"%Y"` || echo "error in date_year with $photo, code $?"
      date_month=`date -r "$photo" +"%m"`|| echo "error in date_month with $photo, code $?"

      # compose target folder for the photo

      # make sure the target folder exists and has proper permissions set
      if [ ! -e $year_dir ]; then
          mkdir "$year_dir"
          chown $IMGUSR:$IMGGRP "$year_dir"
          chmod a+rwx "$year_dir"

      if [ ! -e $photo_dir ]; then
          mkdir "$photo_dir"
          chown $IMGUSR:$IMGGRP "$photo_dir"
          chmod a+rwx "$photo_dir"

      # cp the file, if everything works change to move (mv)
      cp "$photo" "$photo_dir/$photo" || echo "error copying $photo, code $?"


# main program follows

# enable the line below to get the product ID written out (debugging or new device))
# echo "canon.hotplug: $ACTION $PRODUCT" >> /var/log/hotplug.log

if [ "$PRODUCT" == "$CAMERA" ]; then

  echo "`date`: Found the Canon to $ACTION!" >> $LOGFILE

  if [ "$ACTION" == "add" ]; then
    export PATH

    echo `date` > $ERRORLOG
    # create temporary dir, cd there
    if [ ! -e $TMPDIR ]; then
        mkdir $TMPDIR || error "error creating tempdir $TMPDIR"
    cd $TMPDIR
    rm *.JPG *.AVI *.JPEG

    # set info led into cpu control mode
    miconapl -a led_set_cpu_mcon info on

    # get images, while accessing camera info LED blinks

    # during processing switch info LED on
    miconapl -a led_set_on_off info


    # processing complete, switch info LED off
    miconapl -a led_set_on_off info off

    # switch info led back to mcon control
    miconapl -a led_set_cpu_mcon info off

    # do some housekeeping
    # rm -rf $TMPDIR
    echo "`date`: Image processing for Canon complete." >> $LOGFILE


exit 0