Hack 18 Bluetooth File Transfers in Linux

figs/expert.giffigs/hack18.gif

Exchange data freely between your Bluetooth device and your Linux box.

Getting on the Net [Hack #17] from anywhere your cell phone works is pretty darn cool, but your phone probably has other features. Maybe someone messaged you a photo from their family barbecue that you want to copy over to your laptop. Or maybe you just want to install some applications on your shiny new phone.

The heart of file transfer over Bluetooth is called the Object Exchange, or OBEX, protocol, a binary file transfer protocol run over not merely Bluetooth, but also Infrared and even generic TCP/IP. The OpenOBEX project at http://openobex.sf.net/ offers the most ubiquitous open source implementation of the protocol. You can get packages for libopenobex and openobex-apps from the sid distribution, and Red Hat packages for openobex can be had from the SourceForge site or on rpmfind.net. Bluetooth actually supports two different OBEX profiles for transferring files: OBEX Push, which is primarily used for dumping individual files to a Bluetooth device, and OBEX File Transfer, which supports a richer set of file exchange operations.

Unfortunately, the present state of the art in Bluetooth file transfer using Linux is still in considerable flux. The openobex-apps package contains an obex_test application, which offers one very rudimentary way of sending files to your Bluetooth devices. First, you need to figure out which Bluetooth channel your phone or other device uses for OBEX File Transfer; to do this, type:

# sdptool search FTRN Inquiring ... Searching for FTRN on 00:11:22:33:44:55 ... Service Name: OBEX File Transfer Service RecHandle: 0x10003 Service Class ID List:   "OBEX File Transfer" (0x1106) Protocol Descriptor List:   "L2CAP" (0x0100)   "RFCOMM" (0x0003)     Channel: 10   "OBEX" (0x0008)

Now you can try connecting to the device with obex_test, using the -b option (for Bluetooth), the BD address of the device, and the FTRN channel number:

$ obex_test -b 00:11:22:33:44:55 10 Using Bluetooth RFCOMM transport OBEX Interactive test client/server. > c Connect OK! Version: 0x10. Flags: 0x00 > x PUSH filename> /home/sderle/images/image.jpg name=/home/sderle/images/image.gif, size=7294 Going to send /home/sderle/images/image.gif(opt21.gif), 7294 bytes Filling stream!

obex_test proceeds to display some progress messages, followed by a confirmation:

Made some progress... Made some progress... Made some progress... Filling stream! PUT successful!

The file should appear on your device. Similarly, obex_test can receive files sent from your device, if you configure your computer's Bluetooth interface to answer to OBEX Push requests, again using sdptool with the same channel your device uses for OBEX Push:

$ sdptool add --channel=10 OPUSH $ obex_test -b 00:11:22:33:44:55 10 Using Bluetooth RFCOMM transport OBEX Interactive test client/server. > s

obex_test should print a blank line and then pause. Now send a file from your phone via Bluetooth. You'll see a ton of status messages, and then obex_test will report that it's finished. You should be able to find your file in /tmp.

The problem with obex_test, other than a total lack of documentation, is that it's entirely driven by terminal-based user interaction. What if we want to script file transfers or be able to receive files automatically? Another, probably easier way of getting files from your computer to your phone involves a little app called ussp-push, which you can get from http://www.unrooted.net/hacking/ussp-push.tgz. ussp-push is based on some code from the Affix stack, but actually relies on OpenOBEX. Also, it doesn't compile at present right out of the box, so we'll use Perl to tweak it so that it compiles properly with modern versions of OpenOBEX:

# tar xfz ussp-push.tgz # cd ussp-push # perl -pi -e 's/custfunc\.userdata/custfunc.customdata/g' obex_main.c # make ... # cp ussp-push /usr/local/bin

ussp-push relies on having an RFCOMM serial device bound to the Bluetooth channel your device uses for OBEX Push, so we'll first need to fire up sdptool again, and then use rfcomm to bind the device to the listed channel:

# sdptool search OPUSH Inquiring ... Searching for OPUSH on 00:11:22:33:44:55 ... Service Name: OBEX Object Push Service RecHandle: 0x10004 Service Class ID List:   "OBEX Object Push" (0x1105) Protocol Descriptor List:   "L2CAP" (0x0100)   "RFCOMM" (0x0003)     Channel: 9   "OBEX" (0x0008) # rfcomm bind /dev/rfcomm1 00:11:22:33:44:55 9

Now you can use ussp-push to send files to your device.

$ ussp-push /dev/rfcomm1 /home/sderle/images/image.jpg image.jpg

ussp-push takes three arguments: an RFCOMM device, a local file to push, and the name of the file to save it as on the remote side. When you run ussp-push, you'll see an avalanche of progress info, hopefully concluding with the file appearing on your phone. If you create an entry for the new RFCOMM device in /etc/bluetooth/rfcomm.conf, you can have the device bound on boot. Save the following wrapper script as btpush , and save it somewhere handy (such as your ~/bin directory). You can then use it to trivially send files directly to your phone:

#!/bin/bash # btpush - send files to a Bluetooth device using ussp-push # just run it as: btpush <file> ussp-push /dev/rfcomm1 $1 `basename $1`

If you get permissions issues when running ussp-push, make sure your /dev/rfcomm* devices are group-writeable, and are owned by a group that you're a member of.

Similarly, you can receive files using another small app called obexserver , which you can fetch from http://www.frasunek.com/sources/unix/obexserver.c. obexserver needs to be built together with openobex-apps. Once you've built openobex-apps, do the following from within the top-level source directory:

# cd src # wget http://www.frasunek.com/sources/unix/obexserver.c # gcc -o obexserver obexserver.c libmisc.a -lopenobex # cp obexserver /usr/local/bin

To receive files, first set up OBEX Push service on your computer by running sdptool add --channel=10 OPUSH, changing the channel as necessary to match the one your device uses for OBEX Push. Now you can just run obexserver without arguments, and send a file from your phone. obexserver will receive the file, store it in /tmp, and exit.

Being able send files from phone to computer and back is nice, but having to send and receive files individually doesn't present the absolutely most convenient interface. Fortunately, if your Bluetooth device is running the SymbianOS or EPOC operating system this includes Series 60 phones and the Ericsson P800 you can actually mount your device's filesystem on your computer via NFS. The package that performs this minor miracle is called p3nfs, and it's available at http://www.koeniglich.de/p3nfs.html. The source distribution comes with binaries to run on your phone, in case you don't have a cross-compiler (which is likely). The phone application is called nfsapp, and you can find the appropriate binary version for your phone in the bin/ subdirectory, with a .sis extension. Use one of the methods just described to send the appropriate SIS file to your phone and install it there. Next, build and install p3nfsd in the usual way. If you installed the RPM provided by koeniglich.de, you can find the SIS files in /usr/share/doc/p3nfs-[version].

You'll want to create a mount point in your filesystem for the NFS share; p3nfs uses /mnt/psion by default. Also, p3nfs needs its own RFCOMM device, so you'll need set one up. If you're running a Nokia phone, you'll probably want to bind to channel 4; otherwise, you may be using channel 3.

# mkdir /mnt/phone # rfcomm bind /dev/rfcomm2 00:11:22:33:44:55 4

Now, start nfsapp on your phone. Don't worry if you pick the wrong channel at first when you run nfsapp on your phone, it will tell you which channel it's listening to. If you told rfcomm to bind to the wrong one, just run rfcomm unbind /dev/rfcomm2 and try the right channel. At first, nfsapp defaults to listening to the infrared port click the joystick or press the p key to cycle between IR, Bluetooth, and TCP transport. Once you select Bluetooth, nfsapp gives you 30 seconds to start p3nfs on your computer. Assuming everything else is configured correctly, you should be able to start p3nfsd as follows:

# p3nfsd -series60 -tty /dev/rfcomm2 -dir /mnt/phone -user sderle p3nfsd: version 5.13a, using /dev/rfcomm2 (115200), mounting on /mnt/phone p3nfsd: to stop the server do "ls /mnt/phone/exit". (pid 3274)

p3nfsd will probably take a few seconds to finish mounting. A quick look at lsmod will verify that, in fact, it's using your kernel's NFS support. You'll want to replace -series60 with -UIQ or another option if you're not running a Series 60 phone run p3nfsd without any options for a list. You'll want to alter the -tty, -dir, and -user options as appropriate. The -user option isn't strictly necessary, but p3nfsd mounts the share with user-only read and execute permissions, so if you don't use it, you'll need to be root to browse the share. Now you should be able to cd into /mnt/phone, and do all the things you're accustomed to doing in a Unix-like NFS mount. You'll need to ls /mnt/phone/exit to unmount the share, which is a little weird. Otherwise, p3nfsd unmounts after a few minutes of inactivity you can control the timeout using the -timeout option.

By this point, you've got several options for exchanging data between Bluetooth devices. Obviously, you can easily reuse these techniques to exchange files between two Bluetooth-equipped Linux machines as well, and, in fact, these same methods work pretty well for infrared file transfers, with a little tweaking, but that's beyond the scope of this hack. One last thing: if you want your new RFCOMM devices to be there the next time you boot, don't forget to add entries for them to /etc/bluetooth/rfcomm.conf. Now start installing those applications!

Schuyler Erle



Wireless Hacks. 100 Industrial-Strength Tips and Techniques
Wireless Hacks. 100 Industrial-Strength Tips and Techniques
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 158

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net