How can I consistently connect to the same rfcomm port on Linux?

2.5k views Asked by At

I have several bluetooth device that I'm trying to connect to in Linux. I have no problems with any of the devices except for one. The difference is that all the other devices handle their bluetooth connections in (what I assume to be) the standard way, i.e. they wait for the Host device (the PC) to initiate the connection. The other device, on the other hand, tries to initiate the connection itself every few seconds, with a second or so of sleep in between.

For the other devices, I've been connecting like this:

rfcomm connect /dev/rfcommX <deviceMacAddress>

(where X is any unused rfcomm port number)

Before issuing this command, I run the bluetooth-agent with the needed pairing keys. Everything here works fine.

For the device in question, this works great the first time, before the device has been paired. After pairing, however, the rfcomm connect command has a very high likelihood of failing. This is because the device is itself trying to init the connection.. when the device is sleeping, the connection fails ("Host down").

Instead, I've found that, for this device, the following command works like a charm:

rfcomm listen /dev/rfcommX

(I had to add a serial port via sdptool add SP first)

As the PC will sit there and wait for an incoming connection from the device, this works every single time.

However, the problem comes in when I have more than one device. The rfcomm listen command works brilliantly, but there doesn't seem to be a way to control which device (identified by Mac address) connects to which rfcomm port; if more than one device is switched on, then the first one to try and connect will connect, regardless. In our application, however, we want the user to know which device they are connecting to.

Has anyone dealt with anything like this before? We're getting to the point where we're thinking of writing a custom version of the bluez bluetooth package, so any help here would be greatly appreciated :)

2

There are 2 answers

1
Ignacio Vazquez-Abrams On BEST ANSWER

Either write a udev rule that creates a symlink with the same name each time, or follow the appropriate path through /sys to get to the device.

0
Peter Harrison On

While it is unlikely that the OP cares after 11 years, this is what I do to get consistent device names.

I have a bash script that binds each device to a pre-defined port. I keep thinking I will do this in a more clever way, perhaps in python, but this works so I just keep using it:

#! /bin/bash

ADAM_115K=FC:A8:9A:00:49:05
BOB_57K=07:12:05:16:64:16
CLARA_115K=FC:A8:9A:00:48:B5
DREW_115K=98:D3:32:10:B2:5D
EMILY_115K=00:12:05:04:91:88
FRANK_115K=FC:A8:9B:00:44:4B
JEFF_57K=20:17:03:08:60:48
KATY_115K=98:DA:50:01:46:77

case $1 in
  ADAM | adam)
   [ -a "/dev/rfcomm0" ] && sudo rfcomm release 0 
   sudo rfcomm bind 0 $ADAM_115K
   ;;
  BOB | bob)
   [ -a "/dev/rfcomm1" ] && sudo rfcomm release 1
   sudo rfcomm bind 1 $BOB_57K
   ;;
  CLARA | clara)
   [ -a "/dev/rfcomm2" ] && sudo rfcomm release 2
   sudo rfcomm bind 2 $CLARA_115K
   ;;
  EMILY | emily)
   [ -a "/dev/rfcomm3" ] && sudo rfcomm release 3
   sudo rfcomm bind 3 $EMILY_115K
   ;;
  FRANK | frank)
   [ -a "/dev/rfcomm4" ] && sudo rfcomm release 4
   sudo rfcomm bind 4 $FRANK_115K
   ;;
  JEFF | jeff)
   [ -a "/dev/rfcomm5" ] && sudo rfcomm release 5
   sudo rfcomm bind 5 $JEFF_57K
   ;;
  DREW | drew)
   [ -a "/dev/rfcomm6" ] && sudo rfcomm release 6
   sudo rfcomm bind 6 $DREW_115K
   ;;
  KATY | katy)
   [ -a "/dev/rfcomm7" ] && sudo rfcomm release 7
   sudo rfcomm bind 7 $KATY_115K
   ;;
  NONE | none)
   sudo rfcomm release all
   ;;
  ALL | all)
   sudo rfcomm release all
   sudo rfcomm bind 0 $ADAM_115K
   sudo rfcomm bind 1 $BOB_57K
   sudo rfcomm bind 2 $CLARA_115K
   sudo rfcomm bind 3 $EMILY_115K
   sudo rfcomm bind 4 $FRANK_115K
   sudo rfcomm bind 5 $JEFF_115K
   sudo rfcomm bind 6 $DREW_115K
   sudo rfcomm bind 7 $KATY_115K
   ;;
  *)
   echo "Usage: bt-bind [ADAM|BOB|CLARA|EMILY|FRANK|JEFF|KATY|ALL|NONE]"
   ;;
esac
rfcomm -a