Bluetooth connect without pairing

久未见 提交于 2019-12-04 13:23:10

问题


The normal way to connect to a bluetooth device is by pairing.

We need to connect to a device in an abnormal way: By using the Bluetooth MAC address only. We do not want to be prompted for a PIN.

We know the device supports this technique, but we cannot find a way to do it on Android.

The abbreviated code looks like this:

  String mac_address = “00:11:22:33:44:55”
  BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

  BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(mac_address);

  Method m = bluetoothDevice.getClass().getMethod("createRfcommSocket", 
           new Class[] {int.class});
  BluetoothSocket socket = (BluetoothSocket) m.invoke(device, 1);

  socket.connect();

The problem is that upon socket.connect() we are prompted for a PIN. The PIN is not necessary for this device, so we do not want to be prompted for a PIN.

The reason we know the PIN is not necessary:

  1. We manufacture this device and write the firmware.
  2. We can connect to it using a program on windows written in C#.

How can we modify the code such that it will not prompt for a PIN?

[Edit to test suggestion in comment]

We tested method createInsecureRfcommSocketToServiceRecord like this:

ParcelUuid list[] = device.getUuids();
BluetoothSocket  socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(list[0].getUuid());

Then we get error like this:

I/InputDispatcher(  382): Delivering touch to current input target: action: 0x1
I/InputDispatcher(  382): Delivering touch to current input target: action: 0x1
V/BluetoothSocket.cpp(16956): initSocketNative
V/BluetoothSocket.cpp(16956): ...fd 66 created (RFCOMM, lm = 0)
V/BluetoothSocket.cpp(16956): initSocketFromFdNative
I/BluetoothPolicyService(  382): getBluetoothDataTransferAllowed
D/BluetoothUtils(16956): isSocketAllowedBySecurityPolicy start : device null
V/BluetoothService.cpp(  382): createDeviceNative
V/BluetoothService.cpp(  382): ... address =
V/BluetoothEventLoop.cpp(  382): onCreateDeviceResult
V/BluetoothEventLoop.cpp(  382): onCreateDeviceResult
E/BluetoothEventLoop.cpp(  382): onCreateDeviceResult: D-Bus error: org.bluez.Error.AlreadyExists (Already Exists)
D/BluetoothEventLoop(  382): Result of onCreateDeviceResult:1
V/BluetoothService.cpp(  382): discoverServicesNative
V/BluetoothService.cpp(  382): ... Object Path = /org/bluez/1100/hci0/dev_00_11_22_33_44_55
V/BluetoothService.cpp(  382): ... Pattern = , strlen = 0
D/FStest  (  633): check default
D/FStest  (  633): check default

回答1:


It's definitely possible. You should have a look at the Android BluetoothChat demo app at: http://developer.android.com/samples/BluetoothChat/src/com.example.android.bluetoothchat/BluetoothChatService.html they use the insecure channel:

public ConnectThread(BluetoothDevice device, boolean secure) {
    mmDevice = device;
    BluetoothSocket tmp = null;
    mSocketType = secure ? "Secure" : "Insecure";

    // Get a BluetoothSocket for a connection with the
    // given BluetoothDevice
    try {
        if (secure) {
            tmp = device.createRfcommSocketToServiceRecord(
                    MY_UUID_SECURE);
        } else {
            tmp = device.createInsecureRfcommSocketToServiceRecord(
                    MY_UUID_INSECURE);
        }
    } catch (IOException e) {
        Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
    }
    mmSocket = tmp;
}

on the client side. And on the server side:

  public AcceptThread(boolean secure) {
            BluetoothServerSocket tmp = null;
            mSocketType = secure ? "Secure" : "Insecure";

            // Create a new listening server socket
            try {
                if (secure) {
                    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
                            MY_UUID_SECURE);
                } else {
                    tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
                            NAME_INSECURE, MY_UUID_INSECURE);
                }
            } catch (IOException e) {
                Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
            }
            mmServerSocket = tmp;
        }

Keep in mind that you need the Bluetooth MAC address for this. Google is trying to hide the address and make it unusable (to prevent tracking). You'll have problems getting your own MAC address and the MAC addresses of remote devices are randomised and change after some time: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id



来源:https://stackoverflow.com/questions/35953413/bluetooth-connect-without-pairing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!