LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Wireless Networking (https://www.linuxquestions.org/questions/linux-wireless-networking-41/)
-   -   Setting up BlueZ with a passkey/PIN (to be used as headset for iPhone) (https://www.linuxquestions.org/questions/linux-wireless-networking-41/setting-up-bluez-with-a-passkey-pin-to-be-used-as-headset-for-iphone-816003/)

jhaagsma 06-23-2010 04:55 PM

Setting up BlueZ with a passkey/PIN (to be used as headset for iPhone)
 
Hi,

I've been trying to connect a phone to a computer to use as a headset, but have been running into a problem with pairing using a pin/passkey. I would like to be able to set up bluez with a passkey that I can connect with, without requiring any setup per device or per connecting time.

There seem to be a few people who have done the headset bit on the web:

http://jprvita.wordpress.com/2009/12...4-a2dp-stream/
http://acassis.wordpress.com/2008/02...com-bluetooth/ (in portugese but Google Translate does a good job I think)

Regardless, what I'm attempting to do is to connect to the computer with a device, and then begin streaming the data to it.

My installed version of bluez is 4.63-2
Code:

# apt-cache policy bluez
bluez:
  Installed: 4.63-2

Currently I have used the following commands (as I cannot seem to make this configuration happen automatically):
Code:

hciconfig hci0 noencrypt
hciconfig hci0 piscan
hciconfig hci0 name MyHeadset

sdptool add a2snk
sdptool search --bdaddr local a2snk

hciconfig hci0 class 0x200404
hciconfig -a

which allow me to see it from an iPhone (but not an iPod touch) and a (mac) desktop, and a windows laptop. However, while the mac *seems* to connect without a pin, the phone insists on using a pin. (When I say seems, what I mean is that it says it has paired; but when going to select "Use as audio device", it says the the bluetooth audio has failed; this is a similar experience as on the windows laptop).

In an effort to use a pin, I found a guide which advises using bluetooth-agent followed by a pin ( http://wiki.debian.org/BluetoothUser ) which I tried:

Code:

# bluetooth-agent 4835
Pincode request for device /org/bluez/1033/hci0/dev_00_14_51_53_6C_AC
Authorizing request for /org/bluez/1033/hci0/dev_00_14_51_53_6C_AC

which works on the mac desktop; it however does not get to the "authorizing request" bit with an iPhone; Furthermore, this is running something from the command line, whereas I would like to initiate connection without having to set anything up on the "headset" computer.


There is a thread on the forums which is related to a passkey-agent, but the program involved does not seem to exist in my setup (or repository), and may have been deprecated, though I've not found anything clear on that point:
http://www.linuxquestions.org/questi...-fails-700134/


There also exist numerous guides & threads ( http://www.linuxquestions.org/questi...-think-547891/ ) online that talk of an hcid.conf, but apparently ( https://bugs.launchpad.net/ubuntu/+s...ls/+bug/365779 ) the hcid (and consequently the .conf file) was removed in blueZ 4.x


So my question is:

How do I set a pin without running bluetooth-agent from the CLI, and how do I make it work with an iPhone or other device that insists on using a PIN, with bluez 4.X?


Also, if anyone is knowledgeable about the iPod Touch not seeing items that the iPhone can see, that would also solve a related mystery to me. Or if you know more about the bluetooth -> ALSA step that would be useful :)


Thanks for your time if you've read this far :)

Hangdog42 06-25-2010 07:39 AM

I think that you can set a PIN in /etc/bluetooth/hcid.conf. Look for the passkey directive and change it to what you would like. You'll probably then have to restart bluetooth to get it picked up, but after that bluetooth should always ask for the PIN.

jhaagsma 06-29-2010 10:09 AM

Thank you for your reply; I had to make sure I wasn't mistaken again before I responded -- but, as I mentioned in my post, it would seem ( https://bugs.launchpad.net/ubuntu/+s...ls/+bug/365779 ) that the hci daemon (and consequently /etc/bluetooth/hcid.conf ) was removed in Bluez 4.

I don't have an hcid.conf, nor does creating one and filling in options do anything at all, unfortunately.

So I guess I'm looking for an equivalent, but for Bluez 4.6x; Surely they can't have *removed* functionality in a new major version, so I assume I simply haven't figured out how to do this; surely somebody has? :)

Hangdog42 06-29-2010 12:06 PM

I'm sorry, you're completely right about Bluez4 not using hcid.conf anymore. Have you tried echoing to your passkey file?

Code:

echo -n "1234" >/etc/bluetooth/passkeys/default
And set the "1234" to whatever PIN you want?

jhaagsma 06-29-2010 12:59 PM

It appears I don't have a passkeys folder; when I create one and add a default as you say ( and then /etc/init.d/bluetooth restart ) it still will not use that PIN. I hadn't seen anything on that before, something else to look into though...

Incidentally, a potentially related issue is the fact that when I restart the bluetooth daemon i need to run all those hciconfig commands again to set it up properly. There *has* to be some way to set that automatically. For example, in main.conf it has a Class line, but changing that seems to have no effect on the class. If I change the Class line to 0x200404 in main.conf and restart the bluetooth it still comes up as 0x4a010c (which wasn't even what the class in main.conf was set to originally).

It feels many configuration options were removed, and if these were simply moved somewhere else it was definitely not made obvious.

MS3FGX 06-29-2010 03:39 PM

Quote:

Originally Posted by jhaagsma (Post 4018320)
Surely they can't have *removed* functionality in a new major version

Unfortunately, they did.

You can no longer configure PINs in plain-text files as you could under BlueZ 3.x, as it was seen as a security liability. All pairing must now be done through D-BUS calls, so you need a helper application.

jhaagsma 06-29-2010 05:17 PM

Hrm; it might have been nice had they at least done something like hashed passwords like so many other things. But oh well.


Can everything else not be configured as well?

I haven't really seen any documentation on dbus calls for stuff like that; any ideas on what that would entail? As I posted, I tried using

Code:

# bluetooth-agent 4835
where the PIN is 4835. Is this what you mean by a dbus call? (it sounds to me like it is not)

(As mentioned earlier this was only partially successful in one case, as in it connected with a desktop, but not a phone; and further it dropped the connection once I tried to set the item (not even use it) as an audio output device)

Unfortunately, what information have found online regarding BlueZ has been somewhat contradictory, and in large part out of date. The BlueZ wiki which gets referenced occasionally seems to be non-existent at this point (presumably due to becoming out of date), yet Bluez seems to be under active development.

MS3FGX 06-29-2010 05:47 PM

bluetooth-agent is also outdated. The documentation for BlueZ is indeed terrible, it seems like it is intentionally difficult to work with.

If you want to pair a device on the command line, your only option is to use "simple-agent", which is in the /test directory of the BlueZ source. As far as I know it is not included with any BlueZ packages, but I could be wrong on that. It isn't a big deal to pull it from the source tree though.

jhaagsma 06-30-2010 10:38 AM

Hmm I was mainly looking at connecting via the command line for testing purposes; Really, I'd rather have a fixed PIN that I can connect (a phone) to the computer with, without touching the computer at all. If the best way to do this is some other method then I'd prefer to look at that.

The only code snippets I could find were in http://www.kernel.org/doc/ols/2006/o...es-421-426.pdf (below, and from 2006) and http://blogs.gnome.org/jamesh/2006/1...bus-interface/ .

Code:

#!/usr/bin/python

import dbus

bus = dbus.SystemBus();
obj = bus.get_object(’org.bluez’,’/org/bluez’)
manager = dbus.Interface(obj,’org.bluez.Manager’)
obj = bus.get_object(’org.bluez’,manager.DefaultAdapter())
adapter = dbus.Interface(obj,’org.bluez.Adapter’)
adapter.SetName(’My Bluetooth dongle’)

(an example of changing the name of the local device into My Blue-tooth dongle using ... Python)


That doesn't seem too bad. I found the API documentation at http://bluez.cvs.sourceforge.net/blu...xt?view=markup which I hope is up to date, though it is from 2008. However, reading through it, it looks like there is no equivalent command to set the PIN or passkey -- lots about passkey agents &etc, which I don't think I fully understand at this point.

I may have to take a peek at that simple-agent. While I realize that my particular application/goal is non-standard, every time I look at this I keep thinking "there has got to be a simpler way to do this." Wishful thinking perhaps? ;)

KrishnaShetty 08-09-2010 01:51 AM

Pairing with default pin/passkey
 
Hi folks,

I am using the BlueZ version 4.47.

I need to write test code to qualify some BlueZ profiles.

I want auto pair with some default pin(like "0000") when test case is executed from the command line. And I don't want to use GUI.

Please tell me whether it is possible? If possible please tell me the steps to achieve the same.


I tried to set default pin in the 'simple-agent', but it doesn't seem to work :(

thanks,
Krishna

Deepak Meti 12-07-2010 08:07 AM

Hi ,
Anybody got solution.........?

philchetcuti 08-17-2011 03:33 PM

I realize I'm really late to the thread, but I do have a solution that does not require python or a helper.

What you need to do is create folder /var/lib/bluetooth/XX:XX:XX:XX:XX:XX

The XX:XX:XX:XX:XX:XX is the bdaddr of your bluetooth device which you can find from hciconfig hci0 -a

Inside this folder are many files, I've not fully explored what each does (if they do anything, some do not).
What you need to do is create a pincodes file in this folder.
This is your passkey file, although its not universal, you have to put an entry within it for each bluetooth device you want to connect.

Each entry in the pincodes file is in the format
XX:XX:XX:XX:XX:XX 1234

In this case the XX:XX:XX:XX:XX:XX is the bdaddr of the device you want to pair and the 1234 is your pairing code.

You also must have hcid running to make use of this.

With a little scripting you could grep an hcitool scan and create the appropriate file.

Feel free to email me with any questions, I've been working on an embedded system for the last 20 months that makes heavy use of bluetooth. philip.a.chetcuti<AT>gmail.com

SuperMa_ 02-27-2012 01:08 AM

Hi jhaagsma:

I am trying BlueZ 4.96, and also meet this problem. Have you find the solutions?

When I try to use simple-agent, the gobject-introspection is really painful, as its Makefile doesn't support cross-compile.So I fail at this way.

Hasn't the problem been solved? Help


SuperMa_

jwaters42 04-09-2014 11:21 AM

I apologize in advance to replying to a post that is over 2 years old, but this thread is still one of the top Google searches for the topic, and after struggling for a few days, I managed to cobble a solution together. Hopefully this helps somebody else trying to accomplish the same thing later.

I'm using BlueZ 4.101. I'm trying to connect my phone/tablet to an Embedded Linux machine to create a PAN. I want the phone/tablet to prompt me to enter a PIN, and I want the Linux device to authenticate against a hard-coded PIN.

Here's how I solved it.
  1. I disabled SSP on the Linux device. I ran the following command while configuring my BT adapter:
    Code:

    hciconfig hci0 sspmode 0
  2. I copied simple-agent from the bluez test/ directory to my Linux device.
  3. I have a minimal file system on the embedded Linux device- my pygobject module is built without instrospection, so I have to disable that in simple-agent. I replaced this line:
    Code:

    from gi.repository import GObject
    with this line:
    Code:

    import gobject as GObject
  4. By default, simple-agent requests keyboard input for authentication. My system is headless, and I want it to always authenticate against the same key for each device. So I modified the RequestPinCode method to always return the same value, my PIN:
    Code:

            def RequestPinCode(self, device):                   
                    print("RequestPinCode (%s)" % (device))     
                    return "1234"

  5. Since I don't want/need keyboard input, I changed the capability to NoInputNoOutput:
    Code:

            capability = "NoInputNoOutput"
  6. I can now run simple-agent on my device, and the phone/tablet will only pair when the PIN entered matches the hard coded one on the Linux device.

I plan to read the key from a .conf file running on the system instead of hard coding it in simple-agent, but I think there's enough here to get most folks started. The RFS requirements are minimal- a shell (I'm using busybox), bluez, python, dbus-glib, dbus-python, glib2, and pygobject are the only dependencies.

guaycuru 07-23-2015 10:02 AM

Thank you @jwaters42, your answer has helped me a lot.

Please note that step 3 is no longer needed though.

I was successful at running simple-agent but, for some reason, my device still can't connect to my headless system. I'll keep investigating and let everyone know if I have any more to add to this.

bbb123 08-11-2017 07:35 PM

Need help automating solution from jwaters42
 
I followed the steps from jwaters42 (thanks!) and they work for me manually. Now I want to automate the process, but I am having no luck.

Specifically, I am doing the following:

Create directory
/usr/bin/bluez/

Edit /etc/rc.local
Add this line (right before the “exit 0” line).
/usr/bin/bluez/setpin.sh

Create the text file /usr/bin/bluez/setpin.sh
Code:

#!/bin/sh
hciconfig hci0 piscan
hciconfig hci0 sspmode 0
/usr/bin/python /usr/bin/bluez/simple-agent &

Copy these two files into /usr/bin/bluez/
simple-agent
bluezutils.py
These two files are available from downloading and untarring the latest Bluez tar file.
They are both in the test/ directory after you untar.
Copy these two files to the BeagleBone directory /usr/bin/bluez/.

You can make a file executable with these commands:
chmod +x setpin.sh
chmod +x simple-agent

Edit simple-agent
vi /usr/bin/bluez/simple-agent

Comment out contents of AuthorizeService
Code:

        def AuthorizeService(self, device, uuid):
                # print("AuthorizeService (%s, %s)" % (device, uuid))
                # authorize = ask("Authorize connection (yes/no): ")
                # if (authorize == "yes"):
              #        return
                # raise Rejected("Connection rejected by user")

Modify
Code:

        def RequestPinCode(self, device):
                # print("RequestPinCode (%s)" % (device))
                set_trusted(device)
                # return ask("Enter PIN Code: ")
                return "123456"

In main method near the bottom, change capability line to read
Code:

capability = "NoInputNoOutput"

If I start simple-agent manually from a command terminal as follows
/usr/bin/bluez/setpin.sh
and then connect to the Linux beaglebone via Bluetooth from a disconnected laptop, I will be prompted to enter the PIN. I must enter 123456 to match method RequestPinCode. Then the laptop connects. Good!

UNRESOLVED PROBLEM
If I reboot the beaglebone, so that simple-agent is started by /etc/rc.local, which starts /usr/bin/bluez/setpin.sh, then I will NOT be asked to enter a PIN. The laptop just connects. Bad!

Any advice, suggestions, and tips are appreciated.

bbb123 08-22-2017 04:24 PM

I resolved my issue as follows...
 
Continuing from my previous post, but now with the fix:

I remove the line I had added to /etc/rc.local
(I don't use /etc/rc.local now.)

I modify the text file /usr/bin/bluez/setpin.sh as follows
Code:

#!/bin/sh
sleep 120
hciconfig hci0 piscan
sleep 10
hciconfig hci0 sspmode 0
sleep 10
/usr/bin/python /usr/bin/bluez/simple-agent &

As root create a crontab entry with this command.
crontab -e
Choose to use nano and add this line to the end of the file.
Code:

@reboot sleep 5; /usr/bin/bluez/setpin.sh
Exit Nano (Cntl-X) and save (Y).

Also, I had no previous experience with Python and I discovered you need to be really careful with indentation.
I used one or two tabs instead of spaces.
Also, I found that I need to explicitly return from this method
Code:

def AuthorizeService(self, device, uuid):
# print("AuthorizeService (%s, %s)" % (device, uuid))
# authorize = ask("Authorize connection (yes/no): ")
# if (authorize == "yes"):
return
# raise Rejected("Connection rejected by user")

Now after I reboot my beaglebone and wait 2.5 minutes, I am required to enter PIN 123456 when connecting to beaglebone via bluetooth.

There is a weakness with this approach. The beaglebone allows bluetooth connection without PIN during 140 seconds until simple-agent starts up.
You might want to cut down the sleep times (120, 10, 10 seconds) to something more appropriate for your system. However, if simple-agent runs too early, then it fails to start up properly and a PIN is never required.

mirakamali 05-27-2019 09:36 AM

hello, i followed your tutorial. it is good. the phone asks for a password but it is not pairing then with the pi. the phone is saying that the pi is not ready to pair.


All times are GMT -5. The time now is 08:59 AM.