Edgar Huckert: Bluetooth file transfer made simple

The file transfer between two computers via Bluetooth is much simpler than via WLAN: you normally need only two computers - no router between them is needed. Theoretically this is also possible in a WLAN environment if you use an AD-HOC network. Unfortunately I never got this WLAN solution running.

As already tested in another project on my WEB pages (see here) I use Bluetooth RFCOMM sockets over Bluetooth. The API calls needed are exactly the same as for standard TCP sockets. The order of calls (socket, bind, listen, accept etc.) is also identical with the usual sequence for TCP server - client solutions.

The protocol

This solution uses a simple protocol (PUT direction):

With this protocol you can also transfer binary files. It is not as efficient as FTP but much simpler. Normally no additional security features (sequence numbers, checksums) are needed as Bluetooth handles this on the lower levels.

Sources and installation

Here are two simple C source files running under Linux (no: Windows not supported!): Compile these programs with GNU gcc under Linux as indicated in the source code comments in both programs. No make files nor a complicated IDE are needed given the simplicity of the compile commands.

I have tested the programs with a Raspberry 3 (Raspbian 8.0 Jessie), a Laptop under Linux/Ubuntu V17.04 and a desktop computer running Linux/Debian V8.5. The minimum requirement is the installation of the header files and the library libbluetooth. You can install them as follows:
 
   sudo apt-get install libbluetooth-dev  

No complicated Bluetooth GUI-type setup is needed (no explicit pairing, no choice of an application class etc.). No Bluetooth daemons (nor bluetoothd nor obexftpd) are needed. The most important requirement is this: the client needs to know the Bluetooth address of the server (a 6-bytes value). Typical example: B8:27:EB:E1:8F:D8. Normally you get this address on the server side by typing:
 
   sudo hciconfig -a  

This command also returns the name of the Bluetooth device - normally hci0. I normally place the Bluetooth addresses in environment variables. The second requirement: Bluetooth on both sides must be enabled and visible. You can guarantee this by typing:
 
   sudo hciconfig hci0 class 0 reset
   sudo hciconfig hci0 piscan noauth up  

I found that Bluetooth under Linux is problematic if you add the Bluetooth adapter at run time. The error message "cannot connect" can be avoided when you reboot the machine after a hardware change. I have seen the same problems with some WLAN adapters.

Run the programs

To run the file transfer (PUT direction), start the server first on one computer:
 
   ./blue_ftps
 
Then start the client on the second computer:
 
   ./blue_ftpc -btaddr $BTADDR -file xyz  

where BTADDR stands for an environment variable containing the Bluetooth address of the server machine and xyz stands for the file to be placed on the server. If youd add "-v" on the command lines then you will get some logging information on stdout.

Restrictions and performance

This solution has been implemented on Linux only - nor Windows nor Android nor Mac OSX have been tested. I guess however that on Unix-like operating systems (Android, Mac OSX) these programs should work also.

At the moment only PUT requests are implemented, i.e. the client places a file on the server. GET requests will be implemented later. I don't plan to implement directory listing requests.

The implementation of my server allows only one client connection. If you must have several simultaneous client connections then the server must be reimplemented using threads.

As mentioned above the performance is not very high - but the reliability is fine. The performance can be improved by improving the ACK method: here every package requires an ACK - this leads to a loss in performance. Around 3 seconds are lost when the connection is established - I do not know how to avoid this. You may also try higher buffer sizes. Currently a buffer (the content part of a a package) is only 256 btyes long. If you play with longer buffers then less acknowledgements are needed. But be careful: sockets do not allow arbitrary buffer sizes.

Here are some results of my measurements:

These results are valid for short distances (1 - 3 m). When using longer distances (10 m) the performance goes down up to a factor of three. I could not get stable connections for distances larger than 10 meters.


Contact

Copyright for all images, texts and software on this page: Dr. E. Huckert

If you want to contact me: this is my
mail address