I've been setting up a USB-bluetooth adapter so I can transfer files between my phone and computer. You'll need kernel support (in menuconfig look in Networking ---> Bluetooth subsystem support).

With a proper kernel, after plugging in your adapter you should see something like

$ lsmod
Module                  Size  Used by
sco                     6484  2 
bnep                    7889  2 
rfcomm                 25356  4 
l2cap                  27398  16 bnep,rfcomm
btusb                   8762  2 
bluetooth              42079  9 sco,bnep,rfcomm,l2cap,btusb
...
$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 010: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
Bus 003 Device 011: ID 0a5c:4502 Broadcom Corp. Keyboard (Boot Interface Subclass)
Bus 003 Device 012: ID 0a5c:4503 Broadcom Corp. Mouse (Boot Interface Subclass)
Bus 003 Device 013: ID 0a5c:2154 Broadcom Corp. 

Once you've got the kernel working, you should install BlueZ, the userspace Bluetooth stack. On Gentoo, you'll want to enable the test-programs USE flag (which brings in additional stuff like simple-agent). Then run

$ sudo emerge -av net-wireless/bluez

This brings in a bunch of tools, among them hcitool and hciconfig. Check that BlueZ finds your adapter with:

$ hcitool dev
Devices:
        hci0    00:01:02:03:04:05

Put your phone in "discovery mode", and then detect it from the computer with:

$ hcitool scan
Scanning ...
        00:0A:0B:0C:0D:0E       Grayhat

Verify communication with:

$ sudo l2ping 00:0A:0B:0C:0D:0E
Ping: 00:0A:0B:0C:0D:0E from 00:01:02:03:04:05 (data size 20) ...
20 bytes from 00:0A:0B:0C:0D:0E id 200 time 69.85ms
20 bytes from 00:0A:0B:0C:0D:0E id 201 time 9.97ms
20 bytes from 00:0A:0B:0C:0D:0E id 202 time 56.86ms
20 bytes from 00:0A:0B:0C:0D:0E id 203 time 39.92ms
4 sent, 4 received, 0% loss

Pairing

Make computer discoverable with:

$ sudo hciconfig hci0 piscan

which adds ISCAN to hciconfig's output.

To setup pairing, you should setup a pair pin by editing

$ cat /var/lib/bluetooth/00:01:02:03:04:05/pincodes
00:0A:0B:0C:0D:0E 12345
AA:AA:AA:AA:AA:AA 67890
$ /etc/init.d/bluetooth restart

where 00:01:02:03:04:05 is the address for your adapter (from hcitool dev) and the file contains addr pin lines. You can get the addresses of the pair devices with hcitool scan (discussed above). After you edit the pincodes file, you'll have to restart the bluetooth daemon.

$ sudo /etc/init.d/bluetooth restart

If you want to use simple-agent instead of mucking about in /var/lib/bluetooth, usage looks something like

$ simple-agent
Agent registered
RequestPinCode (/org/bluez/16306/hci0/dev_00_0A_0B_0C_0D_0E)
Enter PIN Code: 12345

where you start simple-agent and then initiate pairing from the phone. After entering a pin on the phone, you will be prompted to re-enter the pin by simple-agent.

You can also initiate pairing from your computer with

$ simple-agent hci0 00:0A:0B:0C:0D:0E

Gentoo may need to be told that the cell phone is allowed to connect, so create/edit /var/lib/bluetooth/00:01:02:03:04:05/trusts

$ cat /var/lib/bluetooth/00:01:02:03:04:05/trusts
00:0A:0B:0C:0D:0E [all]

which allows the phone to use any Bluetooth service provided by your computer. It's possible that you can accomplish the same result with something like

$ sudo bluez-test-device trusted 00:0A:0B:0C:0D:0E yes

but I haven't been able to figure out the right syntax yet.

Pushing files from the phone

There are a number of OBEX push servers you can run on your box. My favorite so far is ObexPushD, which is easy to use, GPLv2 licensed, and Git versioned. Can't beat that. I've added an ebuild (app-mobilephone/obexpushd) to my Gentoo overlay for easier installation.

Pushing files to the phone

Check for an OBEX Push service on the phone:

$ sdptool search --bdaddr 00:0A:0B:0C:0D:0E OPUSH
Searching for OPUSH on 00:0A:0B:0C:0D:0E ...
Service Name: Object Exchange
Service RecHandle: 0x10003
Service Class ID List:
  "OBEX Object Push" (0x1105)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 3
  "OBEX" (0x0008)
Profile Descriptor List:
  "OBEX Object Push" (0x1105)
    Version: 0x0100

Push a file to the phone using ussp-push (net-wireless/ussp-push)

$ ussp-push 00:0A:0B:0C:0D:0E@3 LFILE RFILE

which pushes the local LFILE to the remote RFILE.

Note that phone's can be finicky about what they accept. For example, my Casio C721 is running BREW 3.x (see my Java ME post), and has a number of issues:

  • It attempts to detect file type by file extension (so you can't send over a JPG with a .jpeg extension). It pops up an "Unsupported Media" warning if you try.
  • It does not accept music in any of the following formats: (AAC (.aac), MP3 (.mp3), MP4/AAC (.mp4, .m4a), WAV (.wav).
  • It does accept JPGs with a .jpg extension.
  • It does accept VCARDs (with a .vcf extension), but they must have DOS endlines (e.g. via unix2dos).
  • If you include multiple VCARDs in a single file, it enters all the information under the name from the first VCARD.
  • If you send a VCARD whos name matches an already existing contact, it leaves the first contact unaltered and creates a new contact storing the VCARD information.

Both images and VCARDs should get pushed in without directory names. Once the phone guesses the file type from the extension, it seems to save the information in the appropriate place automatically.

obexfs

Note: my phone doesn't support the Bluetooth's File Transfer Profile (FTP), so I haven't been able to test the following commands.

With sys-fs/obexfs you can mount a phone with

$ sudo mount -t fuse obexautofs /tmp/mnt

When you're done, unmount with

$ sudo umount /tmp/mnt

obexautofs scans for available devices, so your device must be visible (discoverable). If that's a pain, you can mount a specific device with

$ sudo mount -t fuse "obexfs#-b00:0A:0B:0C:0D:0E -B3" /tmp/mnt

Depending on your kernel, you may need to load the fuse module before doing all of that:

$ sudo modprobe fuse

Debugging

Use hcidump (net-wireless/bluez-hcidump) to trace the bluetooth stack for debugging.

References

A good deal of this information came from the more detailed Gentoo Bluetooth Guide and Bluetooth Network Aggregation Point Howto.